SQL join and count do net get it together - mysql

I'am a beginner in SQL and have some trouble with joining and counting at the same time.
First let me explain my two tables.
I have the following:
Table: AnalysePageview
id title session more
-----------------------------------------------------
1 a 10 0
2 b 20 1
3 c 30 1
4 d 40 1
5 e 50 1
6 f 60 0
Table: AnalyseEvent
id name session more
-----------------------------------------------------
1 a 10 0
2 b 10 1
3 c 10 1
4 d 20 1
and I would like to join this two and add a line like this:
New Table:
id name session counts (out off AnalyseEvent)
-----------------------------------------------------
1 a 10 3
2 b 20 1
3 c 30 0
4 d 40 0
5 e 50 0
6 f 60 0
I just tried this:
SELECT *,
COUNT( AnalyseEvent.session ) AS totalViews
FROM AnalysePageview
LEFT JOIN AnalyseEvent ON AnalysePageview.session = AnalyseEvent.session
thanks for any help in advance. (my be with a small beginner explanation)

You need a group by:
SELECT apv.id, apv.name, apv.session, COUNT( ae.session ) AS totalViews
FROM AnalysePageview apv LEFT JOIN
AnalyseEvent ae
ON apv.session = ae.session
GROUP BY apv.id, apv.name, apv.session;
I also added table aliases to make the query easier to write and to read.

You need to use group by. Something like:
select apw.id, apw.title, apw.session, count(1)
from AnalysePageview apw
left join AnalyseEvent ae
on apw.session = ae.session
group by apw.id, apw.title, apw.session

Related

MariaDB/MySQL using update inner Join MariaDB is wrong order but correct in MySQL

Would like to seek your help on below:
I want to update the lessonnumber in Table lessons, the logic is lessonnumber will be update listed by order based on the starttime. My laravel code below works in MySQL, but error order occurred in MariaDB.
php
DB::statement('set #i=0;');
$type_id = 2; //lessons type
DB::update("
UPDATE lessons A
INNER JOIN (SELECT * FROM lessons WHERE lessons.type_id = $type_id ORDER BY lessons.starttime ASC LIMIT 30) B
ON B.id = A.id
SET A.lessonnumber = (select #i:=#i+1)
");
id
lessonnumber
startime
1
1
11
2
3
33
3
2
22
4
4
44
5
5
55
Mysql: lessonnumber 1 3 2 4 5 is correct order
id
lessonnumber
startime
1
1
11
2
2
33
3
3
22
4
4
44
5
5
55
MariaDB: lessonnumber 1 2 3 4 5 is error order
Can anyone help to solve my problem? Thank you in advance for your help
You are joining on id so the ordering in the join query is ignored. The correct form of update with order by is https://dev.mysql.com/doc/refman/8.0/en/update.html
SET #I = 0;
UPDATE LESSONS A
SET A.lessonnumber = (select #i:=#i+1)
WHERE TYPE_ID = 2
ORDER BY STARTTIME;

MySQL Query keep numbers which do not fall between a range

Could anyone point me in the correct direction on how to do this SQL query? I have two tables coord_table and rm_table. I would like to perform a query where any coord_table.loc which falls between any rm_table.start_loc or rm_table.end_loc is removed from the result of the query.
coord_table
coord_id loc
____________________
1 9
2 19
3 30
4 55
rm_table
rast_id start_loc end_loc
___________________________
1 10 20
2 50 60
query_result
coord_id loc
_____________
1 9
3 30
EDIT: This should work. It uses the BETWEEN syntax:
SELECT a.* FROM coords_table a
LEFT JOIN
(
SELECT
*
FROM
(
SELECT
coords_id, loc, start_loc, end_loc,
(loc BETWEEN start_loc AND end_loc) as is_between
FROM
coords_table, rm_table
) a
WHERE a.is_between = 1
) b
ON a.coords_id = b.coords_id
WHERE b.coords_id IS NULL
Fiddle: http://sqlfiddle.com/#!9/3acdb/2

Show Items even if 0 rows with group by

I'm trying to get the query below to show for each item for each store the amount of each of 4 items we have.
It works great, and I created the temporary table to try to increase speed but my problem is that if the table has no rows for a certain product that product does not show up at all.
I'd like to show all four products(prodNo) regardless of if there is actually any of rows for that specific store.
I researched this site and could not find something similar enough for me to figure it out.
CREATE TEMPORARY TABLE IF NOT EXISTS temp_invoice_dates AS
(
SELECT Invoice_detail.del_date,invoice_Detail.StoreNo,mast_stores.SDesc, invoice_Detail.ProdNo,sold_qty,retn_price,retn_qty,sold_price FROM Invoice_detail
LEFT JOIN mast_stores on invoice_detail.StoreNO=mast_stores.Snum
LEFT JOIN invoice on invoice_detail.Del_Date=invoice.Del_Date and invoice_detail.Invoice_No=invoice.Invoice_No
WHERE Cnum IN ('200','210') AND invoice_detail.Del_Date >= "2016-03-01" AND invoice_detail.Del_Date < "2016-04-01"
);
SELECT
temp_invoice_dates.StoreNo,
temp_invoice_dates.SDesc,
DATE_FORMAT(temp_invoice_dates.Del_Date,'%Y') as Year,
DATE_FORMAT(temp_invoice_dates.Del_Date,'%M') as Month,
temp_invoice_dates.ProdNo,
mast_items.IDesc,
SUM(sold_qty) as TotalIn,
SUM(retn_qty) as TotalOut,
ROUND(SUM((sold_qty*sold_price)-(retn_qty*retn_price)),2) as NetSales,
CONCAT(ROUND(SUM(retn_qty)/SUM(sold_qty),2)*100,'%') as StalePerc
FROM mast_Items
LEFT JOIN temp_invoice_dates on temp_invoice_dates.ProdNo=mast_items.Inum
WHERE mast_items.Inum in ('3502','3512','4162','4182')
GROUP BY temp_invoice_dates.StoreNo, ProdNo
ORDER BY temp_invoice_dates.StoreNo, ProdNo;
Drop table temp_invoice_dates;
Results are similar to:
StoreNo Product Count....
1 1 1
1 2 5
1 3 2
1 4 1
2 1 14
2 2 1
2 4 4
3 2 33
3 3 3
Where as I'd like it to be
StoreNo Product Count ....
1 1 1
1 2 5
1 3 2
1 4 1
2 1 14
2 2 1
2 3 0
2 4 4
3 1 0
3 2 33
3 3 3
3 4 0
Something like this should work.
SELECT sp.StoreNo, sp.ProdNo
, ...stuff...
, sp.IDesc, sp.SDesc
, ...more stuff...
FROM (
SELECT i.Inum AS ProdNo, s.Snum AS StoreNo
, i.IDesc, s.SDesc
FROM mast_Items AS i, mast_stores AS s
WHERE i.Inum IN ('3502','3512','4162','4182')
) AS sp
LEFT JOIN temp_invoice_dates AS tid
ON sp.ProdNo = tid.ProdNo
AND sp.StoreNo = tid.StoreNo
GROUP BY sp.StoreNo, sp.ProdNo
ORDER BY sp.StoreNo, sp.ProdNo
;
Normally I recommend against cross joins (as seen in the subquery) but in this case it is exactly what is needed. If the query is slow, you can instead insert the subquery results into a temp table beforehand, index that, and then use the temp table in place of the subquery.
(Edit: should use sp fields when available for grouping and results)

Mysql union, left join, group and count

Heres my query
SELECT
fsi_courier_assignment_print_master_listing.master_listing_id,
fsi_master_listing.transmittal_id,
fsi_transmittals.product_name,
fsi_transmittals.transmittal_id
FROM fsi_courier_assignment_print_master_listing
LEFT JOIN fsi_master_listing ON fsi_courier_assignment_print_master_listing.master_listing_id = fsi_master_listing.master_listing_id
LEFT JOIN fsi_transmittals ON fsi_master_listing.transmittal_id = fsi_transmittals.transmittal_id
WHERE dispatch_code_id=".$this->db->escape($dispatch_code_id)."
UNION ALL
SELECT
fsi_courier_assignment_print_master_listing_undelivered.master_listing_id,
fsi_master_listing.transmittal_id,
fsi_transmittals.product_name,
fsi_transmittals.transmittal_id
FROM fsi_courier_assignment_print_master_listing_undelivered
LEFT JOIN fsi_master_listing ON fsi_courier_assignment_print_master_listing_undelivered.master_listing_id = fsi_master_listing.master_listing_id
LEFT JOIN fsi_transmittals ON fsi_master_listing.transmittal_id = fsi_transmittals.transmittal_id
WHERE dispatch_code_id=".$this->db->escape($dispatch_code_id)."
fsi_courier_assignment_print_master_listing table
master_listing_id dispatch_code_id
2 2
5 2
36 2
37 2
134 2
135 2
136 2
137 2
138 2
139 2
140 2
fsi_courier_assignment_print_master_listing_undelivered table
master_listing_id dispatch_code_id
1 2
fsi_master_listing table
master_listing_id transmittal_id
1 1
2 1
5 2
36 2
37 2
134 3
135 3
136 3
137 3
138 3
139 3
140 3
fsi_transmittals table
transmittal_id product_name
1 Name 1
2 Name 2
3 Name 3
What Im trying to do is to get the combined result of product from fsi_courier_assignment_print_master_listing and fsi_courier_assignment_print_master_listing_undelivered where dispatch_code_id='2' and count them
My desire Output would be
Product Name Product Count
Name 1 2
Name 2 3
Name 3 7
Thanks in advance, hope somebody can help me to this..
Your query is fine, you just need to:
Add COUNT with GROUP BY product_name and put your query as a subquery.
The transmittal_id is specified two times in the two union queries, either remove one of them or give them different names (It might work fine in MySQL, but it is recommended not to do so).
So your query will be something like this:
SELECT
t.product_name,
COUNT(*) AS ProductCount
FROM
(
SELECT
ml.master_listing_id,
m.transmittal_id,
t.product_name
FROM fsi_courier_assignment_print_master_listing AS ml
LEFT JOIN fsi_master_listing AS m
ON ml.master_listing_id = m.master_listing_id
LEFT JOIN fsi_transmittals AS t
ON m.transmittal_id = t.transmittal_id
UNION ALL
SELECT
u.master_listing_id,
m.transmittal_id,
t.product_name
FROM fsi_courier_assignment_print_master_listing_undelivered as u
LEFT JOIN fsi_master_listing AS m
ON u.master_listing_id = m.master_listing_id
LEFT JOIN fsi_transmittals AS t
ON m.transmittal_id = t.transmittal_id
) AS t
GROUP BY t.product_name;
This will give you:

MYSQL select query using count (*)

i have a problem concerning a select query in MYSQL
i have two different tables and i want to obtain a certain result
i used COUNT method which gave me only the results (>=1)
But in reality , i want to use all counts with zero included how to do it?
My query is:
SELECT
first.subscriber_id,
second.tag_id,
COUNT(*)
FROM
content_hits first
JOIN content_tag second ON first.content_id=second.content_id
GROUP BY
second.Tag_id,first.Subscriber_id<br>
First table:Content_hits
CONTENT_ID SUBSCRIBER_ID
30 1
10 10
34 4
32 2
40 3
28 3
30 6
31 8
12 3
Second table:Content_tag
CONTENT_ID TAG_ID
1 1
2 1
3 1
4 1
5 1
6 1
7 1
8 1
9 1
10 1
11 2
12 2
13 2
14 2
Result but incomplete For example:Subsrciber6 for tag_id=1 should have a count(*)=0
subscriber_id tag_id COUNT(*)
1 1 4
2 1 7
3 1 2
4 1 1
5 1 3
7 1 2
8 1 1
9 1 1
10 1 3
1 2 2
2 2 3
3 2 2
Now that you have further elaborated on what you actually want to achieve, it can be seen that the problem is much more complex. You actually want all combinations of subscriber_id and tag_id, and then count the number of actual entries in the joined table product. whew. So here goes the SQL:
SELECT combinations.tag_id,
combinations.subscriber_id,
-- correlated subquery to count the actual hits by tag/subscriber when joining
-- the two tables using content_id
(SELECT count(*)
FROM content_hits AS h
JOIN content_tag AS t ON h.content_id = t.content_id
WHERE h.subscriber_id = combinations.subscriber_id
AND t.tag_id = combinations.tag_id) as cnt
-- Create all combinations of tag/subscribers first, before counting anything
-- This will be necessary to have "zero-counts" for any combination of
-- tag/subscriber
FROM (
SELECT DISTINCT tag_id, subscriber_id
FROM content_tag
CROSS JOIN content_hits
) AS combinations
Not sure, but is this what you want?
SELECT first.subscriber_id, second.tag_id, COUNT(*) AS c
FROM content_hits first JOIN content_tag second ON first.content_id=second.content_id
GROUP BY second.Tag_id,first.Subscriber_id HAVING c = 0