combine multiple rows into one rows with several column - mysql

hello im going to select and group by with field x but showing in one row with several column
SELECT * FROM `cityname`
WHERE `city`='mashhad'
group by `city`,`number`
ORDER BY `city`
but i want showing :
mashhad 935 915 937 901

Since you want to all number of each city, and display all the number in separated columns, this will be a table pivot issue, try following query:
SELECT city,
MAX(CASE WHEN number = 935 THEN number ELSE NULL END) AS number_935,
MAX(CASE WHEN number = 915 THEN number ELSE NULL END) AS number_915,
MAX(CASE WHEN number = 937 THEN number ELSE NULL END) AS number_937,
MAX(CASE WHEN number = 901 THEN number ELSE NULL END) AS number_901
FROM cityname
GROUP BY city
Demo Here

Related

How can I get true if there is at least one specific value?

I have a table like this:
user_due_diligence
user_id
cellphone
national_id
postal_code
5
approved
in_progress
in_progress
5
in_progress
approved
not_investigated
5
approved
not_investigated
not_investigated
I want to get 1 row per user_id and either 0 or 1 if there is at least one approved record or not. So the expected result is:
user_id
cellphone
national_id
postal_code
5
1
1
0
Any idea how can I do that?
I know the query should include group by user_id, and case when x = "approved", but I don't know the exact syntax.
in this query I used SUM() and CASE WHEN to match the cases when cellphone, national_id or postal_code equals approved when it's true I add 1 to the summary for each one of them, and at the end you need to group by the user_id to get one result per user_id.
SELECT user_id, SUM(CASE When cellphone LIKE 'approved' THEN 1 ELSE 0 END) AS cellphone ,
SUM(CASE When national_id like 'approved' THEN 1 ELSE 0 END ) AS national_id ,
SUM(CASE WHEN postal_code like 'approved' THEN 1 ELSE 0 END) AS postal_code
FROM user_due_diligence
GROUP BY user_id;

Mysql check empty rows of child elements

I have a query to select all childs (positions) based ob the parent id (order_id):
SELECT * FROM positions WHERE order_id = X
The result looks like:
ID | order_id | checked_1 | checked_2
1 | 1 | J. Doe | M. Doe
2 | 1 | | Mr. Tester
3 | 1 | J. Joe |
Now i need a query to check if the fields checked_1 & checked_2 are not empty of all related childs. So if all fields of the childs are filled, there shoulbe be appear a success notice in frontend.
What is the best way to "migrate" all childs, so that i can afterwards create the php query?
May try this to count if empty value is there:
SELECT count(*) AS count_empty FROM positions
WHERE order_id = X AND (IFNULL(checked_1, '') = '' OR
IFNULL(checked_2, '') = '')
So now, if count_empty is zero you may show the success message.
Try this:
SELECT 'SUCCESS' as '' FROM postions WHERES orderid = x AND (checked_1 IS NOT NULL OR checked_1 = '') AND (checked_2 IS NOT NULL OR checked_2 = '');
We can aggregate here by order, and then check for the presence of an empty checked_1 or checked_2 column, for a given order_id group. You may try the following query:
SELECT
order_id,
CASE WHEN SUM(CASE WHEN COALESCE(checked_1, '') = '' THEN 1 ELSE 0 END) +
SUM(CASE WHEN COALESCE(checked_2, '') = '' THEN 1 ELSE 0 END) = 0
THEN 'valid' ELSE 'invalid' END AS status
FROM positions
WHERE order_id = 1
GROUP BY order_id;
Note that I don't know if the missing values are NULL or actually just empty string. My query covers for both possibilities, but if these missing values be NULL then you can remove my calls to COALESCE. Also, you may remove GROUP BY if you plan on only running this query for a single order_id. Though should you have the need to run the query for multiple orders at a time, what I wrote above should come in handy.
one way to do this:
select MIN(CASE WHEN checked_1 = '' OR checked_2 = '' THEN 0 ELSE 1 END) from positions group by order_id
You will get a '0' if any field is empty or '1' if all are <> ''.
http://sqlfiddle.com/#!9/f7518d/1

complex sql query counting and grouping

in table LOG i have the following entries
userid item role
1 Apple Buyer
2 Banana Seller
3 Apple Buyer
1 Banana Seller
3 Orange Buyer
etc
i'm trying to create the following two tables with SQL. table 1:
item countUser1Buy countUser1Sell
Apple
Banana
Orange
AND TAble 2 (here i mean the mean of totals. as in, the mean of the total apples bought
item alluserBuyTotalMean allUserBuyTotalMedian allUserBuyRange allUserBuyStandardDev
Apple
Banana
Orange
i think the first should be a variation on
`SELECT `item`, `role`, count(`item`) as count FROM `LOG` GROUP BY `item`
which is close, giving me
item role count
Apple Buyer 1
Banana Seller 1
but i cant figure out how to make it as i'm trying to get. the second i'm really stumped. thanks
You need conditional aggregation for this:
SELECT `item`,
COUNT(CASE WHEN role='Seller' THEN 1 END) AS countUserSell,
COUNT(CASE WHEN role='Buyer' THEN 1 END) AS countUserBuy
FROM `LOG`
GROUP BY `item`
First query:
SELECT item
, SUM(role = 'Buyer') AS countUser1Buy
, SUM(role = 'Seller') AS countUser1Sell
FROM LOG
WHERE userid = 1
GROUP BY item;
Second query:
SELECT item
, AVG(total) AS alluserBuyTotalMean
, CONCAT(MIN(total), ' - ', MAX(total)) AS allUserBuyRange
, STDDEV_POP(total) AS allUserBuyStandardDev
FROM (
SELECT item
, COUNT(*) AS total
FROM LOG
WHERE role = 'Buyer'
GROUP BY item, userid
) t
GROUP BY item;
SELECT
`item`
,SUM(CASE WHEN `userid`= 1 AND `role` = 'Buyer' THEN 1 ELSE 0 END) as countUser1Buy
,SUM(CASE WHEN `userid` = 1 AND `role` = 'Seller' THEN 1 ELSE 0 END) as countUser1Sell
FROM `LOG`
GROUP BY Item
You will need to make a new CASE statement for each userid, but this should work. Results in the following:
item countUser1Buy countUser1Sell
Apple 1 0
Banana 0 1
Orange 0 0

Denormalizing result set

I'm trying to denormalize a result set so that I have one record per ID. This is a list of patients with multiple comorbidities. The data currently looks like this:
ID Disease
1 Asthma
1 Cancer
1 Anemia
2 Asthma
2 HBP
And I need it to look like this:
ID Disease1 Disease2 Disease3
1 Asthma Cancer Anemia
2 Asthma HBP <NULL or Blank>
I researched Pivot, but all of the examples I saw used aggregate functions which wouldn't apply.
I have added the row_number function and tried self joins like the following:
case when rownum = 1 then Disease else NULL end Disease1,
case when rownum = 2 then Disease else NULL end Disease2,
case when rownum = 3 then Disease else NULL end Disease3
However, this produces the following:
ID Disease1 Disease2 Disease3
1 Asthma NULL NULL
1 NULL Cancer NULL
1 NULL NULL Anemia
2 Asthma NULL NULL
2 NULL HBP NULL
Any suggestions would be greatly appreciated. I would really like to find a way to accomplish this without having a monstrous block of code (which is what I ended up with when trying to do it). Thanks!
You can use MAX to compact the rows:
select
id,
max(case when rownum = 1 then Disease end) Disease1,
max(case when rownum = 2 then Disease end) Disease2,
max(case when rownum = 3 then Disease end) Disease3
from (
select
id,
disease,
rownum = ROW_NUMBER() OVER (partition by id order by id)
from your_table
) sub
group by id
Sample SQL Fiddle

SQL Count() not giving desired results

I am having some difficulties figuring out this SQL statement.
Here is the schema of the table.
studentID |subjectID | attendanceStatus | classDate |
1234567 ... 1 .....
1234567 ... 0
Basically I want to count the attendance percentage based on the studentID and display them in columns like this
studentID | subjectID | attendancePercentage
attendancePercentage is the number of 0s / total entries for that student
Here is what I did and it wasn't giving the desired results.
SELECT studentID, COUNT(attendanceStatus = 0) AS Absent,
COUNT( attendanceStatus = 1) As Present
FROM attendance WHERE studentID = '1234567';
That failed.
I hope that I made sense of what I am trying to achieve.
I think you need use sum instead.
SELECT studentID ,
SUM(CASE WHEN attendanceStatus = 0 THEN 1
ELSE 0
END) AS Absent ,
SUM(CASE WHEN attendanceStatus = 1 THEN 1
ELSE 0
END) AS Present
FROM attendance
WHERE studentID = '1234567'