I am new to sql and I really tried to solve this problem on my own, but no success…
Hope someone can help.
I have 3 tables:
Auth_user
+--------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| username | varchar(30) | NO | UNI | NULL | |
| first_name | varchar(30) | NO | | NULL | |
| last_name | varchar(30) | NO | | NULL | |
| email | varchar(75) | NO | | NULL | |
| password | varchar(128) | NO | | NULL | |
| is_staff | tinyint(1) | NO | | NULL | |
| is_active | tinyint(1) | NO | | NULL | |
| is_superuser | tinyint(1) | NO | | NULL | |
| last_login | datetime | NO | | NULL | |
| date_joined | datetime | NO | | NULL | |
+--------------+--------------+------+-----+---------+----------------+
catalog_presents
+-------------+----------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+----------------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(48) | NO | | NULL | |
| slug | varchar(50) | NO | UNI | NULL | |
| amount | smallint(5) unsigned | NO | | 0 | |
| points | smallint(5) unsigned | NO | | 500 | |
| created_at | datetime | NO | | NULL | |
| updated_at | datetime | NO | | NULL | |
| active | tinyint(1) | NO | | NULL | |
| image | varchar(100) | YES | | NULL | |
| description | longtext | YES | | NULL | |
+-------------+----------------------+------+-----+---------+----------------+
catalog_orders
+------------+----------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+----------------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| user_id | int(11) | NO | MUL | NULL | |
| status | smallint(5) unsigned | NO | | 0 | |
| present_id | int(11) | NO | MUL | NULL | |
| address_id | int(11) | NO | MUL | NULL | |
| created_at | datetime | NO | | NULL | |
| updated_at | datetime | NO | | NULL | |
+------------+----------------------+------+-----+---------+----------------+
I am trying to select a user and check whether he ordered a particular present and write to the row accordingly, then check another one, and another one and so on.
Basically I would like the results to look like this:
id present1 present2 present3 present4
1 1 0 0
2 1 1 1
3 0 0 0
4 1 0 1
where 1 is user placed an order on that type of present and 0 is he didn’t.
My query looks like this
select auth_user.id, case when present_id = 1 from auth_user
left join catalog_orders on catalog_orders.user_id = auth_user.id
left join catalog_presents on catalog_presents.id = catalog_orders.present_id
The problem is that all different orders by users are sorted in multiple rows like this:
id present1 present2 present3 present4
1 1 0 0
2 1 0 0
2 0 1 0
2 0 0 1
3 0 0 0
4 1 0 0
4 0 0 1
Can somebody please help me solve this? Thanks in advance!
This is a kind of pivot table.
You are on the right path, but you need to combine your results down to a single row per user.
Use an aggregate
MAX()perauth_user.idto collapse them into a single row. TheCASEsupplies a zero or one for each present, and theMAX()then selects the greatest value of all rows for theauth_user.id, which will be1if the present was bought and0otherwise.Specifically for MySQL, you don’t need the
CASEsince the boolean comparisonpresent_id = 1will return a 1 or 0 on its own. This is not portable to all other RDBMS though. The method above is preferred.