mysql group by return all the rows - mysql

I have two tables (table 1 and table 2). Table 1 consists the options and table 2 consists the result for each options.
**table1** table2
id id
optionvalue optionvalueid
time (unixtime)
So when the data is inserted it will be stored in table2. There are 5 optionvalue in table 1 and when data is inserted, then in the table2 it will insert the optionvalueid of table 1 and timestamp in unixtimestamp. Eaach month, I want to count the number of values for each optionvalue. Evene if there is no value for an optionvalue, I still want to see count as zero.
I did the following query but only return the value with rows with data only.
SELECT
po.id,po.optionvalue, COUNT(pr.optionvalueid) as votes,
FROM_UNIXTIME(`time`, '%m-%Y') as ndate
FROM table 1
LEFT JOIN table 2 pr ON po.id=pr.optionvalueid
GROUP BY ndate, po.optionvalue ORDER BY ndate ASC
Is there any other ways to make the query so that it will return all the options even if there is no value.

You can CROSS join table1 to the distinct months of table2 and then LEFT join to table2 to aggregate:
SELECT t.ndate, t1.id, t1.optionvalue, COUNT(t2.optionvalueid) votes
FROM table1 t1
CROSS JOIN (SELECT DISTINCT FROM_UNIXTIME(`time`, '%m-%Y') ndate FROM table2) t
LEFT JOIN table2 t2 ON t1.id = t2.optionvalueid AND t.ndate = FROM_UNIXTIME(t2.`time`, '%m-%Y')
GROUP BY t.ndate, t1.id, t1.optionvalue
ORDER BY t.ndate ASC

Related

JOIN Only if One Matching Record in both tables

Essentially I need to only LEFT JOIN on the 2 tables if there is one customerid matching in table2. If there is more than 1 record matching table2 it should not count as a match.
Currently I am doing the following:
SELECT DISTINCT
table1.customerid,
table1.name AS customer,
table2.locationid,
table2.locationname
FROM
table1
LEFT JOIN table2 ON table1.customerid = table2.customerid
WHERE
ORDER BY
name ASC
The issue is it matches on all records.
To clarify -- if customerid is in table2 more than once, it should not join on the match, only if customerid is listed once for a record in table2.
How can this be done?
Join with a subquery that only returns customer IDs that have count = 1.
SELECT DISTINCT
table1.customerid,
table1.name AS customer,
table2.locationid,
table2.locationname
FROM table1
LEFT JOIN (
SELECT customerid, MAX(locationid) AS locationid, MAX(locationname) AS locationname
FROM table2
GROUP BY customerid
HAVING COUNT(*) = 1
) AS table2 ON table1.customerid = table2.customerid
ORDER BY name ASC
Note that using LEFT JOIN means that if locationid is not in table2 at all, the query will still return a row for that location, with NULL in the table2 fields. And with this change, it will also return those null rows when there's more than 1 matching row. If you want those rows omitted from the results entirely, use INNER JOIN rather than LEFT JOIN.

SQL query to get 2 values from table 1 and join all possible option from table 2

I want to get value from table1 and join all matching value from table2. The table1 has to be limited to 2 rows, but expecting output should own all matching values for those two ids.
How can I achieve this?
You would use a subquery:
select t1.*, t2.*
from (select t1.*
from table1 t1
limit 10
) t1 left join
table2 t2
on t1.id = t2.table1_id;
Note: This returns two arbitrary rows. Normally, you would have an order by to better specify the rows. And use order by rand() for random rows.
if you want all the value in join for only two row of table 1 you can use a subqiuery with limit 2
select b.id, a.value, b.value2, b.table1_ID
from (
select * from table1
limit 2
) a
inner join table2 on aid = b.table1_ID

Obtaining only certain values (sql)

I have 3 different tables: table1, table2, table3
Table 1 contains all the different orders that were purchased
Table 2 contains the detail of every order (i mean, it contains a
column called ORDER_DETAIL and the number represent an item of
that order -a unique value)
Table 3 contains the workflow.. some numbers that were inside
ORDER_DETAIL from Table 2 will appear here because this item must be
approved to be delivered
I want to obtain all the different orders whose items did not appear in Table 3.
This picture explains everything:
This is my SQLFIDDLE: http://sqlfiddle.com/#!9/5bfc22/2
I did this query but i am not getting what i want:
select * from table1 kio
inner join table2 jio on kio.ORDER_NUMBER = jio.ORDER_NUMBER
where jio.CANCELLED = 0
and not exists (select 1 from table3 gio where jio.ORDER_DETAIL = gio.ORDER_DETAIL)
Also, how can i obtain those orders whose ORDER_DETAILs only appear on TABLE 2 AND those orders whose order_details appear in table 3 with PROCESSED = 1 and APPROVED = 1? All in the same query.
You can use aggregation: join table1 with table2, then left join table3, aggregate by order_number and filter on groups that have no match in table3.
select t1.id, t1.order_number
from table1 t1
inner join table2 t2 on t2.order_number = t1.order_number
left join table3 t3 on t3.order_detail = t2.order_detail
group by t1.id, t1.order_number
having count(t3.order_detail) = 0
In your DB Fiddle, this produces:
id order_number
3 46646
Also, how can i obtain those orders whose ORDER_DETAILs only appear on TABLE 2 AND those orders whose order_details appear in table 3 with PROCESSED = 1 and APPROVED = 1? All in the same query
For this, you can just add another pair of conditions in the having clause:
having
count(t3.order_detail) = 0
or (max(t3.processed) = 1 and max(t3.approved) = 1)
Yields:
id order_number
1 78945
3 46646
I want to obtain all the different orders whose items did not appear in Table 3.
This seems like a reasonable interpretation of the question, although you add more questions later.
If so, then you don't seem to need table1:
select t2.order_number
from table2 t2 left join
table3 t3
on t2.ORDER_DETAIL = t3.ORDER_DETAIL
group by t2.order_number
having count(t3.ORDER_DETAIL) = 0;

Mysql can't join two tables columns into one show

I want to show two columns summarize data.
table1 - count all fields that the id same as the id on the show_users table.
table2 - sum all values that the id same as the id on the show_users table.
This is my query:
SELECT show_users.id, COUNT(`table1`.id) as sum_fields , SUM(`table2`.count) as count_all
FROM `show_users`
LEFT JOIN `table1` ON `show_users`.id = `table1`.id
LEFT JOIN `table2` ON `show_users`.id = `table2`.id
GROUP by show_users.id
ORDER BY sum_fields DESC
The table2 results are fine, but the table1 count isn't correct values...
Why is that?
SELECT show_users.id, COUNT(DISTINCT `table1`.id) as sum_fields , SUM(`table2`.count) as count_all

SQL - joining data

Is it possible to get 1 result where I require data from 3 tables.
First table: I will need to grab all the fields (1 row found by a primary key)
Second table: I will need to grab the field 'username' (connected to first table by 'master_id')
Third table: I will need to grab the latest added row with the associated master_id key (table has 'date', 'master_id', 'previous_name').
select top 1 first.*, second.username, third.*
from first
inner join second on first.id = second.master_id
inner join third on first.id = third.master_id
order by
third.date desc
As always there are dozens of ways to skin a cat, I'm not sure if this is optimized as the subquery methods, but it should work.
You can join the three tables together. Then, you can use a "filter" join to keep only the latest Table3 row:
select *
from Table1 t1
join Table2 t2
on t2.master_id = t1.master_id
join Table3 t3
on t3.master_id = t1.master_id
join (
select master_id
, max(date) as max_date
from Table3
group by
master_id
) as filter
on t3.master_id = filter.master_id
and t3.date = filter.max_date
You'll need a correlated subquery for that third table.
SELECT t1.*, username, date, previous_name
FROM FirstTable t1
INNER JOIN SecondTable t2 ON t1.master_id=t2.master_id
INNER JOIN
(SELECT master_id, date, previous_name
FROM ThirdTable AS t3_1
WHERE date = (
SELECT MAX(date)
FROM ThirdTable AS t3_2
WHERE t3_2.master_id=t3_1.master_id)) q1 ON q1.master_id=t1.master_id;
NOTE: Untested.