Mysql distinct sum, group by - mysql

This is my table:
id user_id type value
1 1 type1 2
2 2 type1 1
3 1 type2 5
4 1 type1 2
I want output like this:
user_id type1 type2
1 4 5
2 1 0
please help

You can try like this:
SELECT
user_id,
sum( if( type = 'type1', value, 0 ) ) AS type1,
sum( if( type = 'type2', value, 0 ) ) AS type2
FROM
table_name
GROUP BY
user_id;

I think, this is what you are searching for:
select
user_id,
(select sum(value) from <yourtablename> sub1 where type = 'type1' where sub1.user_id = baseTable.user_id) as type1,
(select sum(value) from <yourtablename> sub2 where type = 'type2' where sub2.user_id = baseTable.user_id) as type2,
from
<yourtablename> baseTable

Related

I'm hoping to sort the items returned in the following query by the order they're entered into the IN() function

I'm hoping to sort the items returned in the following query by the order they're entered into the IN() function.
SELECT t1.product_id
, SUM(t1.quantity)
FROM tb_invoice_detail t1
, tb_products t2
WHERE t1.del_date > DATE_ADD(SYSDATE(), INTERVAL - 1 MONTH)
AND t1.del_f = '1'
and t1.product_id = t2.id
AND IFNULL(t2.price_discount, t2.price) BETWEEN 0 AND 100
and t2.rate >= 0
GROUP
BY t1.product_id
ORDER
BY SUM(t1.quantity) DESC;
Result:
product_id, SUM(t1.quantity)
100320 8
100004 7
100210 5
100226 5
100321 4
100418 3
100002 2
100000 2
100001 2
100474 2
100268 2
When I get list data using product_id
SELECT
id,
name,
thumbnail,
description,
price,
IFNULL(price_discount, price) AS price_discount,
rate,
number_total,
number_current,
(CASE
WHEN number_current = 0 THEN 2
WHEN (ROUND(number_current / number_total * 100) < 20) THEN 1
ELSE 0
END) AS state
FROM
tb_products
WHERE
id IN (100320 , 100004,
100210,
100226,
100321,
100418,
100002,
100000,
100001,
100474,
100268)
=>
SELECT
id,
name,
thumbnail,
description,
price,
IFNULL(price_discount, price) AS price_discount,
rate,
number_total,
number_current,
(CASE
WHEN number_current = 0 THEN 2
WHEN (ROUND(number_current / number_total * 100) < 20) THEN 1
ELSE 0
END) AS state
FROM
tb_products
WHERE
id IN (100320 , 100004,
100210,
100226,
100321,
100418,
100002,
100000,
100001,
100474,
100268)

Count Age With Distinctly in MySQL

I have a table like this
PersonID Gender Age CreatedDate
================================
1 M 32 10/09/2011
2 F 33 10/09/2011
2 F 33 10/11/2011
1 M 32 10/11/2011
3 F 33 10/11/2011
I want to find Gender Count By Age with group by created date,The age range will be 30-34 and getting person will be distinctly.
Desired output should like this:
Gender AgeRange CreatedDate CountResult
================================
M 30_34 10/09/2011 1
F 30_34 10/09/2011 1
F 30_34 10/11/2011 1
So I tried this but couldtn help:
SELECT t.Gender,'30_34' AS AgeRange,t.CreatedDate,
SUM(CASE WHEN t.Age BETWEEN 30 AND 34 THEN 1 ELSE 0 END) AS CountResult,
FROM (
SELECT DISTINCT PersonID,Gender,Age,CreatedDate
FROM MyTable
GROUP PersonID,Gender,Age,CreatedDate
HAVING COUNT(PersonID)=1
) t
What can I do for solution?
Thanks
If you are want the earliest created date per personid this might do
drop table if exists mytable;
create table mytable(PersonID int, Gender varchar(1),Age int, CreatedDate date);
insert into mytable values
(1 , 'M', 32 , '2011-09-10'),
(2 , 'F', 33 , '2011-09-10'),
(2 , 'F', 33 , '2011-11-10'),
(1 , 'M', 32 , '2011-11-10'),
(3 , 'F', 33 , '2011-11-10');
select mt.gender,
mt.createddate,
sum(case when mt.age between 32 and 34 then 1 else 0 end) as Age32to34
from mytable mt
where createddate = (select min(mt1.createddate) from mytable mt1 where mt1.personid = mt.personid)
group by gender,mt.createddate
How about:
SELECT
Gender
, '30_34' AS AgeRange
, CreatedDate
, COUNT(*) AS CountResult
FROM MyTable A
JOIN (
SELECT PersonID, MIN(CreatedDate) MinCreatedDate
FROM MyTable GROUP BY PersonID
) B ON B.PersonID = A.PersonID AND B.MinCreatedDate = A.CreatedDate
WHERE Age BETWEEN 30 AND 34
GROUP BY Gender, CreatedDate
ORDER BY CreatedDate, Gender DESC
You would appear to want:
SELECT t.Gender, '30_34' AS AgeRange, t.CreatedDate,
COUNT(DISTINCT t.PersonId) AS CountResult
FROM MyTable
WHERE t.Age BETWEEN 30 AND 34
GROUP BY t.Gender, t.CreatedDate;

mysql - why condition where is not work?

SELECT
t1.user_id,
count(*) total,
sum(case when t1.var1 = 'yes' then 1 else 0 end) as type1,
sum(case when t1.var1 = 'no' then 1 else 0 end) as type2
FROM table as t1
WHERE type1 > 0
GROUP by t1.user_id
ORDER by type1 DESC
LIMIT 100
In result i get rows:
user_id total type1 type2
1 100 80 20
4 120 70 50
6 90 0 90
Tell me please why condition WHERE type1 > 0 not work and how select rows with this condition ?
The WHERE only works on the original value and not on a variable you just made by summing the other values up, you can use HAVING for this:
SELECT
t1.user_id,
count(*) total,
sum(case when t1.var1 = 'yes' then 1 else 0 end) as type1,
sum(case when t1.var1 = 'no' then 1 else 0 end) as type2
FROM table as t1
GROUP by t1.user_id
HAVING type1 > 0
ORDER by type1 DESC
LIMIT 100
See here for another example of using HAVING: http://www.w3schools.com/sql/sql_having.asp

Loop through table records

I have a table with a list of names in it as below
+----------+
| CLI_NAME |
+----------+
| A |
| B |
| C |
| D |
| E |
+----------+
I'd like to loop through this something like
for each value in CLI_NAME do
{
bla bla
}
For each value in the table CLI_NAMES, I'd like to loop through and execute the below.
The value selected from the table above needs to go in as a parameter to T_NAME such as T_NAME = "abc" in the query below
INSERT INTO TABLE_2(DATE, O_WT)
SELECT
F_DATE,
CASE
WHEN
SUM(
CASE
WHEN
F_NAME like 'ty%asd%'
THEN
F_PKEY
END
) = 1 THEN 1
WHEN
SUM(
CASE
WHEN
F_NAME like 'ty%asd%'
THEN
F_PKEY
END
) = 2 THEN 2
WHEN
SUM(
CASE
WHEN
F_NAME like 'ty%asd%'
THEN
F_PKEY
END
) BETWEEN 3 AND 5 THEN 3
WHEN
SUM(
CASE
WHEN
F_NAME like 'ty%asd%'
THEN
F_PKEY
END
) > 5 THEN 5
ELSE 0
END AS O_WT
FROM
TABLE_1
WHERE
F_NAME IN (
SELECT I_NAME from I_WD WHERE I_I_ID IN (
SELECT I_MAP_ID FROM T_T_MAP where T_MAP_ID = (
SELECT T_ID FROM TWD WHERE T_NAME = 'abc'
)
)
)
AND F_DATE between '2015-05-01' and '2015-06-01'
AND F_NAME LIKE 'ty%pr%'
GROUP BY F_DATE
How could I loop through & do this please?
If I understand correctly, you can do what you want using CROSS JOIN:
INSERT INTO TABLE_2(DATE, O_WT)
SELECT t1.F_DATE,
(CASE WHEN SUM(CASE WHEN t1.F_NAME like 'ty%asd%' THEN t1.F_PKEY END) = 1 THEN 1
WHEN SUM(CASE WHEN t1.F_NAME like 'ty%asd%' THEN t1.F_PKEY END) = 2 THEN 2
WHEN SUM(CASE WHEN t1.F_NAME like 'ty%asd%' THEN t1.F_PKEY END) BETWEEN 3 AND 5 THEN 3
WHEN SUM(CASE WHEN t1. F_NAME like 'ty%asd%' THEN t1.F_PKEY END) > 5 THEN 5
ELSE 0
END)
END AS O_WT
FROM TABLE_1 t1 CROSS JOIN
CLI_NAMES
WHERE t1.F_NAME IN (SELECT I_NAME
FROM I_WD
WHERE I_I_ID IN (SELECT I_MAP_ID
FROM T_T_MAP
WHERE T_MAP_ID = (SELECT T_ID
FROM TWD
WHERE T_NAME = 'abc'
)
)
) AND
t1.F_DATE between '2015-05-01' and '2015-06-01' AND
t1.F_NAME LIKE 'ty%pr%'
GROUP BY t1.F_DATE
So you want 'abc' in WHERE T_NAME = 'abc' replaced with the CLI_NAME?
Does this suffice:
select i_map_id from t_t_map where t_map_id in
(
select t_id from twd where t_name in (select cli_name from cli_names)
)
instead of
select i_map_id from t_t_map where t_map_id =
(
select t_id from twd where t_name = 'abc'
)
It would not quite be the same as a loop. E.g. if 'A' and 'B' lead to the same t_ids, then you'd get the inserts just once instead of twice.

If not found in record then get other where case in mysql

Need to check in where case that if not found where type='P' then it take record of type='C'
here is table
paper_id | product_id | type
1 1 P
2 1 P
3 1 C
4 1 C
5 2 C
6 2 C
There is product_id 1 and 2, need to get those record that have type='P' but those product who have not type='P' the record get from record type='C'
after query need this result
paper_id | product_id | type
1 1 P
2 1 P
5 2 C
6 2 C
i try
select * from table where CASE WHEN type !='P' THEN type='C' ELSE type='P'END
but not working
select paper_id, product_id, type from your_tab
where type = 'P'
union all
select t1.paper_id, t1.product_id, t1.type from your_tab t1
where t1.type = 'C'
and not exists (select 1 from your_tab t2
where t2.product_id = t1.product_id and t2.type = 'P');
maybe this will help
SELECT DISTINCT T.PRODUCT_ID, T.PAPER_ID, T.TYPE
FROM YOUR_TABLE T
WHERE (CASE
WHEN T.TYPE = 'P' THEN
'TRUE'
WHEN T.TYPE != 'P' THEN
(CASE
WHEN (SELECT COUNT(*)
FROM YOUR_TABLE T2
WHERE T2.PRODUCT_ID = T.PRODUCT_ID
AND T2.TYPE = 'P') = 0 THEN
'TRUE'
ELSE
'FALSE'
END)
END) = 'TRUE'