Combining all data with a unique ID - MySQL - mysql

I have this data that I got from my current query.
What I want to do is combine and make it a single row where the type is Senior, the cashamount and Tenderamount are the same as well.
This is my desired result:
I'm getting my data from this table:
Here's my query:
SELECT a.DATE as `DATE`, a.employee as `EMPLOYEE`, a.TYPEID, a.NAME as
`NAME`, (select (case when a.typeid = 1 then a.amount else NULL end)) as
`CASHAMOUNT`,
(select (case when a.typeid <> 1 then a.amount else NULL end)) as
`TENDERAMOUNT`, (select gndtndr.IDENT from gndtndr where gndtndr.TYPE = 12
and `gndtndr`.`CHECK`= a.CHECK and gndtndr.DATE = a.DATE) as `ID`,
from gndtndr a
where STR_TO_DATE(a.DATE, '%m/%d/%Y') BETWEEN '20170901' AND '20170901'
order by STR_TO_DATE(a.DATE, '%m/%d/%Y')

My MySQL is a bit rusty, but give this a try!
SELECT a.Date, a.Employee, a.Name, a.ID, SUM(b.Amount) AS CashAmount,
SUM(c.Amount) AS TenderAmount FROM
(SELECT DISTINCT Date, Employee, Name, ID FROM gndtndr WHERE Type = 12) AS a
LEFT JOIN gndtndr AS b
ON a.ID = b.ID AND b.TypeID = 1
LEFT JOIN gndtdr AS c
ON a.ID = c.ID and c.TypeID <> 1
GROUP BY a.Date, a.Employee, a.Name, a.ID

I've figured it out :) I just have to define the type conditions in my where clause where the type is 1(for cash).
SELECT a.DATE as `DATE`, a.employee as `EMPLOYEE`, a.TYPEID, a.NAME as
`NAME`, (select sum(gndtndr.amount) from gndtndr where gndtndr.typeid = 1
and gndtndr.`CHECK` = a.`CHECK` and gndtndr.DATE = a.DATE) as `CASHAMOUNT`,
(select (case when a.typeid <> 1 then a.amount else NULL end)) as
`TENDERAMOUNT`, (select gndtndr.IDENT from gndtndr where gndtndr.TYPE = 12
and `gndtndr`.`CHECK`= a.CHECK and gndtndr.DATE = a.DATE) as `ID` from
gndtndr a
where a.TYPEID <> 1 and STR_TO_DATE(a.DATE, '%m/%d/%Y') BETWEEN '20170901'
AND '20170901' order by STR_TO_DATE(a.DATE, '%m/%d/%Y')

Related

Mysql - Min and Max per month as oppose to daily?

The query below does its job to select the min, max, start and last price per day in a given month.
I would like to select the same but for the whole month, as in show the overall performance for the given month instead of on a daily basis.
Fiddle: http://sqlfiddle.com/#!9/ca4867/10
SELECT maxminprice.metal_id,
maxminprice.metal_price_datetime_IST,
maxminprice.max_price,
maxminprice.min_price,
firstlastprice.first_price,
firstlastprice.last_price
FROM (SELECT metal_id,
DATE(metal_price_datetime) metal_price_datetime_IST,
MAX(metal_price) max_price,
MIN(metal_price) min_price
FROM metal_prices
GROUP BY metal_id,
DATE(metal_price_datetime)
ORDER BY metal_id,
DATE(metal_price_datetime_IST)) maxminprice
INNER JOIN (SELECT mp.metal_id,
day_range.metal_price_datetimefl,
SUM(CASE
WHEN TIME(mp.metal_price_datetime_IST) = first_time
THEN
mp.metal_price
ELSE NULL
END) first_price,
SUM(CASE
WHEN TIME(mp.metal_price_datetime_IST) = last_time
THEN
mp.metal_price
ELSE NULL
END) last_price
FROM metal_prices mp
INNER JOIN (SELECT metal_id,
DATE(metal_price_datetime_IST)
metal_price_datetimefl,
MAX(TIME(metal_price_datetime_IST))
last_time,
MIN(TIME(metal_price_datetime_IST))
first_time
FROM metal_prices
GROUP BY metal_id,
DATE(metal_price_datetime_IST))
day_range
ON mp.metal_id = day_range.metal_id
AND DATE(mp.metal_price_datetime_IST) =
day_range.metal_price_datetimefl
AND TIME(mp.metal_price_datetime_IST) IN
( last_time, first_time )
GROUP BY mp.metal_id,
day_range.metal_price_datetimefl) firstlastprice
ON maxminprice.metal_id = firstlastprice.metal_id
AND maxminprice.metal_price_datetime_IST =
firstlastprice.metal_price_datetimefl
AND maxminprice.metal_price_datetime_IST BETWEEN '2018-02-01' AND LAST_DAY('2018-02-01')
ORDER BY metal_id, metal_price_datetime_IST DESC
Here is the query changed to work for each month. I have not changed the column names so you might need to look into doing that for better maintenance. Also, I have not tested this with data for multiple months or over years so you should do that before you start using it.
SELECT maxminprice.metal_id,
maxminprice.metal_price_datetime_IST,
maxminprice.max_price,
maxminprice.min_price,
firstlastprice.first_price,
firstlastprice.last_price
FROM (SELECT metal_id,
DATE_FORMAT(metal_price_datetime_IST, "%Y%m") metal_price_datetime_IST,
MAX(metal_price) max_price,
MIN(metal_price) min_price
FROM metal_prices
GROUP BY metal_id,
DATE_FORMAT(metal_price_datetime_IST, "%Y%m")
ORDER BY metal_id,
DATE_FORMAT(metal_price_datetime_IST, "%Y%m")) maxminprice
INNER JOIN (SELECT mp.metal_id,
day_range.metal_price_datetimefl,
SUM(CASE
WHEN mp.metal_price_datetime_IST = first_time
THEN
mp.metal_price
ELSE NULL
END) first_price,
SUM(CASE
WHEN mp.metal_price_datetime_IST = last_time
THEN
mp.metal_price
ELSE NULL
END) last_price
FROM metal_prices mp
INNER JOIN (SELECT metal_id,
DATE_FORMAT(metal_price_datetime_IST, "%Y%m")
metal_price_datetimefl,
MAX(metal_price_datetime_IST)
last_time,
MIN(metal_price_datetime_IST)
first_time
FROM metal_prices
GROUP BY metal_id,
DATE_FORMAT(metal_price_datetime_IST, "%Y%m")) day_range
ON mp.metal_id = day_range.metal_id
AND DATE_FORMAT(mp.metal_price_datetime_IST, "%Y%m") =
day_range.metal_price_datetimefl
AND mp.metal_price_datetime_IST IN
( last_time, first_time )
GROUP BY mp.metal_id,
day_range.metal_price_datetimefl) firstlastprice
ON maxminprice.metal_id = firstlastprice.metal_id
AND maxminprice.metal_price_datetime_IST =
firstlastprice.metal_price_datetimefl

MySQL SELECT query with another SELECT

I have the next sql query:
SELECT CONCAT(v.p_sery, v.p_id) AS sery,
(SELECT COUNT(1) FROM v where p_delivery_result = 1) AS delivery_count,
(SELECT COUNT(1) FROM v where p_delivery_result = 2) AS ND1,
(SELECT COUNT(1) FROM v where p_delivery_result = 3) AS ND2,
(SELECT COUNT(1) FROM v where p_delivery_result = 4) AS ND3,
(SELECT COUNT(1) FROM v where p_delivery_result = 5) AS ND4,
(SELECT COUNT(1) FROM v where p_delivery_result = 6) AS ND5,
(SELECT COUNT(1) FROM v where p_delivery_result = 7) AS ND6,
(SELECT COUNT(1) FROM v where p_delivery_result = 8) AS ND7
FROM (
SELECT p_sery, p_id, d.p_delivery_result
FROM registries AS a, registry_regulations r, delivery d
WHERE a.p_id = r.registry_id AND d.p_id = r.regulation_id AND (SELECT
STR_TO_DATE(a.p_date_created, '%Y-%m-%d') BETWEEN '2017-04-01' AND '2017-06-01')
) as v;
But this not working.
Error: Table v doesn't exist
What I do wrong?
I have this tables:
And I want get the count of one of the status in table delivery
You cannot access the derived table from the context of a correlated subquery. Try this query instead:
SELECT CONCAT(v.p_sery, v.p_id) AS sery,
COUNT(CASE WHEN p_delivery_result = 1 THEN 1 END) AS delivery_count,
COUNT(CASE WHEN p_delivery_result = 2 THEN 1 END) AS ND1,
COUNT(CASE WHEN p_delivery_result = 3 THEN 1 END) AS ND2,
COUNT(CASE WHEN p_delivery_result = 4 THEN 1 END) AS ND3,
COUNT(CASE WHEN p_delivery_result = 5 THEN 1 END) AS ND4,
COUNT(CASE WHEN p_delivery_result = 6 THEN 1 END) AS ND5,
COUNT(CASE WHEN p_delivery_result = 7 THEN 1 END) AS ND6,
COUNT(CASE WHEN p_delivery_result = 8 THEN 1 END) AS ND7
FROM (
SELECT p_sery, p_id, d.p_delivery_result
FROM registries AS a
JOIN registry_regulations r ON a.p_id = r.registry_id
JOIN delivery d d.p_id = r.regulation_id
WHERE STR_TO_DATE(a.p_date_created, '%Y-%m-%d')
BETWEEN '2017-04-01' AND '2017-06-01') as v;
Note: Always uses modern, explicit JOIN syntax instead of old-fashioned, implicit syntax.
just remove as before V
FROM (
SELECT p_sery, p_id, d.p_delivery_result
FROM registries AS a, registry_regulations r, delivery d
WHERE a.p_id = r.registry_id AND d.p_id = r.regulation_id AND (SELECT
STR_TO_DATE(a.p_date_created, '%Y-%m-%d') BETWEEN '2017-04-01' AND '2017-06-01')
) v

Return the original value if there is a null in the computation

I'm having trouble with my query in getting only the original value if its computing a null value from another type. I'm computing those original values according to type 5 minus to typeid 10.
Please take note that my data structure and my data types are all over the place and will be hard to read for new users. In order to determine the value, you have to focus on type and typeid.
The type that I get in getting the original value for the discounts is 5
Here are the query and original values:
Query:
select a.ID as `ID`, a.DOB as `DATE`, a.AMOUNT as `TOTAL`, (SELECT
coalesce(sum(case when gndsale.type= "5" then gndsale.amount end), 0) from
gndsale where gndsale.ID = b.ID and gndsale.DOB = a.DOB having
sum(gndsale.type = "5") > 0 ) as `DISCOUNTS` FROM gndsale a
INNER JOIN emp b ON a.ID = b.ID
WHERE a.type = "22" and STR_TO_DATE(a.DOB, '%m/%d/%Y') BETWEEN '2017-05-01'
AND '2017-05-31' GROUP BY TOTAL order by STR_TO_DATE(a.DOB, '%m/%d/%Y')
I have a typeid of 10 that will determine another discount which is senior
Here are the query and the values of senior
Query:
select a.ID as `ID`, a.DOB as `DATE`, a.AMOUNT as `TOTAL`, (SELECT
coalesce(sum(case when gndsale.typeid= "10" then gndsale.amount end), 0) from
gndsale where gndsale.ID= b.ID and gndsale.DOB = a.DOB having
sum(gndsale.typeid = "10") > 0 ) as `DISCOUNTS` FROM gndsale a
INNER JOIN emp b ON a.ID= b.ID
WHERE a.type = "22" and STR_TO_DATE(a.DOB, '%m/%d/%Y') BETWEEN '2017-05-01'
AND '2017-05-31' GROUP BY TOTAL order by STR_TO_DATE(a.DOB, '%m/%d/%Y')
I have a null value with my Senior Discount.
What I want to do is I want to minus the original Discounts value and the Senior Discounts value which means I have to minus the value that has a type = 5 and a typeid = 10 . Fortunately, I was able to compute and I got my result
HERE IS THE PROBLEM I have a null value on my expected result. The problem is because its computing a null value from the Senior result what I want is that the null value should return only the Original Discount Value if its computing null values.
Here's my query:
select a.ID as `ID`, a.DOB as `DATE`, a.AMOUNT as `TOTAL`, (SELECT
coalesce(sum(case when gndsale.type= "5" then gndsale.amount end), 0) -
coalesce(sum(case when gndsale.TYPEID= "10" then gndsale.amount end), 0) END
from gndsale where gndsale.ID= b.ID and gndsale.DOB = a.DOB having
sum(gndsale.type = "5") > 0 and sum(gndsale.TYPEID= "10") > 0 ) as `OTHER
DISCOUNT` FROM gndsale a INNER JOIN emp b ON a.ID= b.ID WHERE a.type
= "22" and STR_TO_DATE(a.DOB, '%m/%d/%Y') BETWEEN '2017-05-01' AND '2017-05-
31' GROUP BY TOTAL order by STR_TO_DATE(a.DOB, '%m/%d/%Y')
Note: THEY ARE BASED ON THE DATES and I can't post pictures yet.. My current result I'm having is on the Other Discount.

MYSQL: combine 2 count sql group by year

i have 2 Table with same structure, each of it i use the almost the same sql to select and SUM.
SQL1:
SELECT YEAR, SUM(GENERATION) AS generationA, SUM(TRANSMISSION) AS transmissionA
FROM tableA
WHERE YEAR BETWEEN '2013' AND '2016'
AND POWER_PLANT_ID = 'ABC1'
AND STATUS = 'V'
AND transmission IS NOT NULL
GROUP BY YEAR
SQL2:
SELECT YEAR, SUM(GENERATION) AS generationB, SUM(TRANSMISSION) AS transmissionB
FROM tableB
WHERE YEAR BETWEEN '2013' AND '2016'
AND POWER_PLANT_ID = 'ABC1'
AND STATUS = 'V'
AND transmission IS NOT NULL
GROUP BY YEAR
how to combine this 2 sql to group by its year?
Try this
select year, sum(generationA) as generationA, sum(transmissionA) as transmissionA from
(
SELECT YEAR, SUM(GENERATION) AS generationA, SUM(TRANSMISSION) AS transmissionA
FROM tableA
WHERE YEAR BETWEEN '2013' AND '2016'
AND POWER_PLANT_ID = 'ABC1'
AND STATUS = 'V'
AND transmission IS NOT NULL
GROUP BY YEAR
union all
SELECT YEAR, SUM(GENERATION) AS generationB, SUM(TRANSMISSION) AS transmissionB
FROM tableB
WHERE YEAR BETWEEN '2013' AND '2016'
AND POWER_PLANT_ID = 'ABC1'
AND STATUS = 'V'
AND transmission IS NOT NULL
GROUP BY YEAR
) as t
group by YEAR
You can use a join
SELECT
a.YEAR
, SUM(a.GENERATION) AS generationA
, SUM(a.TRANSMISSION) AS transmissionA
, SUM(b.GENERATION) AS generationB
, SUM(b.TRANSMISSION) AS transmissionB
FROM tableA as a
LEFT JOIN tableB as b on (a.YEAR = b.year
and a..POWER_PLANT_ID = b.POWER_PLANT_ID
and a.STATUS = b.STATUS
and a.transmission = b.transmission)
WHERE a.YEAR BETWEEN '2013' AND '2016'
AND a.POWER_PLANT_ID = 'ABC1'
AND a.STATUS = 'V'
AND a.transmission IS NOT NULL
GROUP BY a.YEAR
Try with the below script,if you wanted to sum up the the result sets by grouping with year.
SELECT YEAR,SUM(GENERATION) generation,SUM(TRANSMISSION)TRANSMISSION
FROM
(SELECT YEAR, GENERATION , TRANSMISSION
FROM tableA
WHERE YEAR BETWEEN '2013' AND '2016'
AND POWER_PLANT_ID = 'ABC1'
AND STATUS = 'V'
AND transmission IS NOT NULL
UNION ALL
SELECT YEAR, GENERATION, TRANSMISSION
FROM tableB
WHERE YEAR BETWEEN '2013' AND '2016'
AND POWER_PLANT_ID = 'ABC1'
AND STATUS = 'V'
AND transmission IS NOT NULL )AS t
GROUP BY YEAR

MySQL "Trending"

I'm selecting "ideas" from my database currently, but another requirement is to be able to grab "trending ideas", that is, the top 10 most-up-voted ideas within the last 7 days.
My query for selecting "ideas" is this:
SELECT
t.id AS 'id',
CONCAT(t.first_name, ' ', SUBSTRING(t.last_name,1,1)) AS 'name',
t.votes_up,
t.votes_down,
t.votes_aggregate,
GROUP_CONCAT(DISTINCT tags.name) AS 'tags',
t.createdon AS 'timestamp'
FROM (
SELECT
ideas.id, first_name, last_name, createdon,
COALESCE(SUM(case when value > 0 then value end),0) votes_up,
COALESCE(SUM(case when value < 0 then value end),0) votes_down,
COALESCE(SUM(value),0) votes_aggregate
FROM ideas
LEFT JOIN votes ON ideas.id = votes.idea_id
GROUP BY ideas.id
) as t
LEFT JOIN tags_rel ON t.id = tags_rel.idea_id
LEFT JOIN tags ON tags_rel.tag_id = tags.id
How would I get and display all the votes, but only get the "ideas" that have been voted up (votes_up) within the last 7 days and ordered by the amount of votes_up ?
This is my attempt:
SELECT
t.id AS 'id',
CONCAT(t.first_name, ' ', SUBSTRING(t.last_name,1,1)) AS 'name',
t.votes_up,
t.votes_down,
t.votes_aggregate,
GROUP_CONCAT(DISTINCT tags.name) AS 'tags',
t.createdon AS 'timestamp'
FROM (
SELECT
ideas.id, first_name, last_name, createdon,
COALESCE(SUM(case when value > 0 then value end),0) votes_up,
COALESCE(SUM(case when value < 0 then value end),0) votes_down,
COALESCE(SUM(value),0) votes_aggregate
FROM ideas
LEFT JOIN votes ON ideas.id = votes.idea_id
GROUP BY ideas.id
) as t
LEFT JOIN tags_rel ON t.id = tags_rel.idea_id
LEFT JOIN tags ON tags_rel.tag_id = tags.id
WHERE t.published = 1
AND (
SELECT ideas.id,
COALESCE(SUM(case when value > 0 then value end),0) votes_up
FROM ideas
LEFT JOIN votes ON ideas.id = votes.idea_id
WHERE votes.`timestamp` > (NOW() - INTERVAL 7 DAY)
GROUP BY ideas.id
) as v
GROUP BY t.id
ORDER BY v.votes_up DESC
But I get the error for the right syntax to use near 'as v GROUP BY t.id ORDER BY v.votes_up DESC LIMIT 10'
You're using the 'AS v' in a WHERE clause, which isn't possible:
WHERE t.published = 1
AND (
SELECT ideas.id,
COALESCE(SUM(case when value > 0 then value end),0) votes_up
FROM ideas
LEFT JOIN votes ON ideas.id = votes.idea_id
WHERE votes.`timestamp` > (NOW() - INTERVAL 7 DAY)
GROUP BY ideas.id
) as v
Try this one, in your SELECT statement you do the subquery, in your WHERE you check if this isn't NULL and you can order by it (if i'm right):
SELECT
t.id AS 'id',
CONCAT(t.first_name, ' ', SUBSTRING(t.last_name,1,1)) AS 'name',
t.votes_up,
t.votes_down,
t.votes_aggregate,
GROUP_CONCAT(DISTINCT tags.name) AS 'tags',
t.createdon AS 'timestamp',
(
SELECT ideas.id,
COALESCE(SUM(case when value > 0 then value end),0) votes_up
FROM ideas
LEFT JOIN votes ON ideas.id = votes.idea_id
WHERE votes.`timestamp` > (NOW() - INTERVAL 7 DAY)
GROUP BY ideas.id
) AS vup
FROM (
SELECT
ideas.id, first_name, last_name, createdon,
COALESCE(SUM(case when value > 0 then value end),0) votes_up,
COALESCE(SUM(case when value < 0 then value end),0) votes_down,
COALESCE(SUM(value),0) votes_aggregate
FROM ideas
LEFT JOIN votes ON ideas.id = votes.idea_id
GROUP BY ideas.id
) as t
LEFT JOIN tags_rel ON t.id = tags_rel.idea_id
LEFT JOIN tags ON tags_rel.tag_id = tags.id
WHERE t.published = 1
AND vup IS NOT NULL
GROUP BY t.id
ORDER BY vup DESC