Difficulty in resolving union query - ms-access

I have 2 tables:
S_tbl
====================
id | barcode | qty |
====================
1 | 1234 | 10 |
1 | 111 | 5 |
1 | 1234 | 10 |
K_tbl
=============================
id | barcode | qty | newQty |
=============================
1 | 1234 | 10 | 20 |
I run this query:
SELECT K_Tbl.id, K_Tbl.barcode, K_Tbl.Qty, K_Tbl.NewQty
FROM K_Tbl where K_Tbl.id = 1
UNION ALL
SELECT S_Tbl.id, S_Tbl.barcode, S_Tbl.Qty, '0' as NewQty
FROM S_Tbl where S_Tbl.id = 1
and I get this:
=============================
id | barcode | qty | newQty |
=============================
1 | 1234 | 10 | 20 |
1 | 1234 | 10 | 20 |
1 | 1234 | 10 | 0 |
1 | 111 | 5 | 0 |
How to merge same lines that the result will be like this:
=============================
id | barcode | qty | newQty |
=============================
1 | 1234 | 10 | 20 |
1 | 1234 | 10 | 20 |
1 | 111 | 5 | 0 |
EDIT:
i add the line: 1 | 1234 | 10 | to S_Tbl
what i need to change in the query:
SELECT K_Tbl.id, K_Tbl.barcode, K_Tbl.Qty, K_Tbl.NewQty
FROM K_Tbl where K_Tbl.id = 1
UNION
SELECT S_Tbl.id, S_Tbl.barcode, S_Tbl.Qty, K_Tbl.NewQty
FROM S_Tbl
left join K_Tbl on S_Tbl.id=K_Tbl.id and S_Tbl.barcode=K_Tbl.barcode
where S_Tbl.id = 1
that i'll see
=============================
id | barcode | qty | newQty |
=============================
1 | 1234 | 10 | 20 |
1 | 1234 | 10 | 20 |
1 | 111 | 5 | 0 |
Right now I see:
=============================
id | barcode | qty | newQty |
=============================
1 | 1234 | 10 | 20 |
1 | 111 | 5 | 0 |

SELECT K_Tbl.id, K_Tbl.barcode, K_Tbl.Qty, K_Tbl.NewQty
FROM K_Tbl where K_Tbl.id = 1
UNION
SELECT S_Tbl.id, S_Tbl.barcode, S_Tbl.Qty, K_Tbl.NewQty
FROM S_Tbl
left join K_Tbl on S_Tbl.id=K_Tbl.id and S_Tbl.barcode=K_Tbl.barcode
where S_Tbl.id = 1
SQL FIDDLE
I am sure this Query will work from MS-ACCES

Use UNION instead of UNION ALL - slower, but cares about the duplicates and removes them. Refer to MSDN doc: http://msdn.microsoft.com/en-us/library/office/bb208962(v=office.12).aspx
By default, no duplicate records are returned when you use a UNION
operation; however, you can include the ALL predicate to ensure that
all records are returned. This also makes the query run faster.
And it is also same in Oracle or MSSQL.

Related

GROUP sum BY two tables by joining

I'm trying to write a SQL query that will correctly group sales items sold_qyt and sub-total-price together as per product's category so I can show this on the printable invoice that product from Jelly Sheet = 4 at a rate of 62 subtotal for this category product is 248(4 * 62 = 248). but when I try to run the below-mentioned query it shows out-put as 12 but I want subtotal and sold_qyt segregated base on category.
I have tried to run different queries just one query gives the output which is mentioned below and this is for just the sum of all sold_qyt. DB example is also shown below
DB Example: (For better understanding)
Table # 1:
Category
ID | code | name
1 | 1 | jelly sheet
2 | 2 | 9D Glass
3 | 3 | Polished Glass
Table # 2:
Product:
ID | code | name | cost | category_id | price
1 | 1 | IP11JS | 50 | 1 | 62
2 | 2 | IP12JS | 50 | 1 | 62
3 | 3 | IP119D | 40 | 2 | 55
4 | 4 | IP129D | 40 | 2 | 55
5 | 5 | IP11PG | 18 | 3 | 25
6 | 6 | IP12PG | 18 | 3 | 25
Table # 3:
sale_items:
ID | sale_id | product_id | product_code | product_name | unit_price | sold_qyt | subtotal |
1 | 1 | 1 | 1 | IP11JS | 62 | 2 | 124 |
2 | 1 | 2 | 2 | IP12JS | 62 | 2 | 124 |
3 | 1 | 3 | 3 | IP119D | 55 | 2 | 110 |
4 | 1 | 4 | 4 | IP129D | 55 | 2 | 110 |
5 | 1 | 5 | 5 | IP11PG | 25 | 2 | 50 |
6 | 1 | 6 | 6 | IP12PG | 25 | 2 | 50 |
7 | 2 | 7 | 1 | IP11JS | 62 | 2 | 124 |
8 | 2 | 8 | 2 | IP12JS | 62 | 2 | 124 |
9 | 2 | 9 | 3 | IP119D | 55 | 2 | 110 |
10 | 2 | 10 | 4 | IP129D | 55 | 2 | 110 |
11 | 2 | 11 | 5 | IP11PG | 25 | 2 | 50 |
12 | 2 | 12 | 6 | IP12PG | 25 | 2 | 50 |
SQL Query which is run by me:
SELECT sale_id,
SUM(sold_qyt) AS sold_qyt
FROM sale_items
GROUP BY sale_id
kindly help me with this difficulty thanks in advance
Update: 1-21-2021
i execute new query
SELECT (sma_sale_items.sale_id, sma_categories.code AS sma_products.category_id, sma_products.code AS sma_sale_items.product_code,)
SUM(sold_qyt) AS sold_qyt
SUM(subtotal) AS subtotal
FROM sma_sale_items
LEFT JOIN sma_products ON sma_products.id=sma_sale_items.product_id
LEFT JOIN sma_categories ON sma_categories.code=sma_products.category_id
GROUP BY sma_sale_items.sale_id
ORDER BY sma_categories
but no luck :(
I want the output like this:
Expected OUT PUT:
ID | sale_id | category_name | sold_qyt | subtotal |
1 | 1 | Jelly Sheet | 4 | 248 |
2 | 1 | 9D Glass | 4 | 220 |
3 | 1 | Polished Glass | 4 | 100 |
4 | 2 | Jelly Sheet | 4 | 248 |
5 | 2 | 9D Glass | 4 | 220 |
6 | 2 | Polished Glass | 4 | 100 |
The ID column in your expected result set is very misleading - it appears to be just new ID value for the output result set rather than any of the ID values from the source tables.
If it is important for you then you can use this query:
SELECT ROW_NUMBER() OVER (ORDER BY sale_id, category_id),
sale_id,
category_name,
sold_qty,
subtotal
FROM (
SELECT c.ID as category_id,
si.sale_id,
c.[name] as category_name,
SUM(si.sold_qty) as sold_qty,
SUM(si.subtotal) as subtotal
FROM sale_items si
JOIN product p ON p.ID = si.product_code
JOIN category c ON c.ID = p.category_id
GROUP BY c.ID,
si.sale_id,
c.[name]
) r
If it is not relevant and you only want the sale_id, category_name and the totals then simplify it to:
SELECT si.sale_id,
c.[name] as category_name,
SUM(si.sold_qty) as sold_qty,
SUM(si.subtotal) as subtotal
FROM sale_items si
JOIN product p ON p.ID = si.product_code
JOIN category c ON c.ID = p.category_id
GROUP BY si.sale_id,
c.[name]
ORDER BY sale_id, category_name

Update records based on date on MySQL using joins

I have all those tables above.
car_model_tbl
-----------------------------
id | car_model_name|status |
-----------------------------
1 | seria_1 | 1 |
-----------------------------
2 | golf_4 | 1 |
-----------------------------
3 | C_Class | 1 |
-----------------------------
4 | golf_5 | 1 |
-----------------------------
5 | seria_2 | 0 |
-----------------------------
car_manufacturer_tbl
-------------------------
id |car_manufactu_name |
-------------------------
1 | bmw |
-------------------------
2 | volkswagen |
-------------------------
3 | mercedes |
-------------------------
car_service_tbl
---------------------------------
id | model_id| service_date |
---------------------------------
1 | 1 | 2018-03-10 |
---------------------------------
2 | 2 | 2018-02-10 |
---------------------------------
3 | 1 | 2018-01-10 |
---------------------------------
4 | 1 | 2017-12-10 |
---------------------------------
5 | 2 | 2017-12-10 |
---------------------------------
6 | 3 | 2018-02-10 |
---------------------------------
7 | 2 | 2018-01-10 |
---------------------------------
9 | 4 | 2018-03-10 |
---------------------------------
10 | 4 | 2018-02-10 |
---------------------------------
11 | 5 | 2018-02-10 |
---------------------------------
car_model_manufacturer_relation
-------------------------------------------------
id | model_id | manufactu_id| service_status |
-------------------------------------------------
1 | 1 | 1 | 1 |
-------------------------------------------------
2 | 5 | 1 | 1 |
-------------------------------------------------
3 | 2 | 2 | 1 |
-------------------------------------------------
4 | 4 | 1 | 1 |
-------------------------------------------------
5 | 2 | 2 | 1 |
-------------------------------------------------
6 | 3 | 3 | 1 |
-------------------------------------------------
I need to update car_model_manufacturer_relation.service_status = '0'
where car_service_tbl.service_date < "2018-03-01".
In this case car_model_manufacturer_relation.service_status of models 2, 3 and 5 should be set to '0' because every car_service_tbl.service_date for these models is smaller than "2018-03-01".
However, for models 1 and 4 car_model_manufacturer_relation.service_status should stay '1' because even that they have records smaller than "2018-03-01" they also have bigger dates ex. "2018-03-10".
I am trying to create a query for this but until now without success.
You'll need to nest a grouped query, to get the MAX date per model, and update from that.
update car_model_manufacturer_relation as cmmr,
(select model_id, max(service_date) as check_date
from car_service_tbl
group by model_id) as cst
set cmmr.service_status = '0'
where cmmr.model_id = cst.model_id
and cst.check_date < "2018-03-01"
Where you're using more than one table and the table names include underscores, I try and alias the tables to make the code a little shorter and easier on the eye, hence the use of cmmr and cst as table aliases.
The MAX date has also been renamed for clarity as check_date. You can of course name this anything you wish.
With sub query:
UPDATE car_model_manufacturer_relation c
LEFT join (SELECT model_id, service_date FROM car_service_tbl ORDER BY service_date DESC LIMIT 1) as s ON s.model_id = c.model_id
SET service_status=0
WHERE c.service_date < "2018-03-01"
#tyro - be careful with your solution, as a LEFT JOIN would update the service status to 0 when there wasn't a service date within the car_service_tbl. You would need to use a full join, rather than just the LEFT JOIN as you suggested in order to update the records correctly I feel.

Need result for the MySQL joins for this method

I have two table one is order_details and second is orders.
1) order_details
id | order_id | item | order_units | is_cancelled |
------------------------------------------------------------------
1 | 00001 | Mobile | 2 | 0 |
2 | 00001 | Headphone | 2 | 0 |
3 | 00001 | cover | 5 | 0 |
4 | 00002 | charger | 1 | 0 |
5 | 00002 | mobile | 1 | 0 |
6 | 00004 | Tablet | 2 | 0 |
7 | 00005 | Mobile | 1 | 0 |
8 | 00005 | Battery | 2 | 1 |
9 | 00006 | Mobile | 1 | 0 |
10 | 00006 | speaker | 1 | 0 |
11 | 00006 | Motinor | 1 | 0 |
12 | 00007 | Laptop | 2 | 0 |
2) orders
order_id | date | time |total_amount| round |discount|refund
-----------------------------------------------------------------------
00001 | 2017-06-16 |10:10:45 | 456.12 |-0.12 | 0 | 0
00002 | 2017-06-16 |10:25:45 | 600.00 | 0.00 | 10 | 50
00004 | 2017-06-16 |11:10:45 | 300.55 |-0.05 | 0 | 0
00005 | 2017-06-16 |12:10:45 | 200.45 | 0.05 | 20 | 0
00006 | 2017-06-16 |12:40:45 | 685.00 | 0.00 | 50 | 0
00007 | 2017-06-24 |14:10:45 | 888.35 | 0.15 | 0 | 0
I want to join the "order_details" with "orders" and the result should be as below:
---------------------------------------------------------------------
date | time | hour |order_count| total_units| net_amount
---------------------------------------------------------------------
| 2017-06-16 |10:10:45 | 10 | 2 | 11 | 996
| 2017-06-16 |11:10:45 | 11 | 1 | 2 | 300.50
| 2017-06-16 |12:40:45 | 12 | 2 | 4 | 180.50
--------------------------------------------------------------------
I have created a sql query for the above result format and all columns outputs are correct except the "total_units", its showing null.
The following query i have used:
SELECT hdr.date,hdr.time, LPAD(HOUR(hdr.time),2,'0') AS hour, COUNT(hdr.`order_id`) AS order_count, dtl.total_units, SUM((hdr.total_amount+hdr.round-hdr.discount)-hdr.refund) AS net_amount
FROM orders hdr
LEFT JOIN (
SELECT order_id, SUM(qty) AS total_units
FROM order_details
WHERE is_cancelled=0) dtl ON dtl.order_id = hdr.order_id
WHERE DATE(hdr.date) = '2017-06-16 ' AND (HOUR(hdr.time) BETWEEN ('10') AND ('12'))
GROUP BY hdr.date, HOUR(hdr.time)
Please help me to correct this query and generate the exact output as above.
Sorry, One correction in my query..
SELECT hdr.date,hdr.time, LPAD(HOUR(hdr.time),2,'0') AS hour, COUNT(hdr.`order_id`) AS order_count, dtl.total_units, SUM((hdr.total_amount+hdr.round-hdr.discount)-hdr.refund) AS net_amount
FROM orders hdr
LEFT JOIN (
SELECT order_id, SUM(order_units) AS total_units
FROM order_details
WHERE is_cancelled=0) dtl ON dtl.order_id = hdr.order_id
WHERE DATE(hdr.date) = '2017-06-16 ' AND (HOUR(hdr.time) BETWEEN ('10') AND ('12'))
GROUP BY hdr.date, HOUR(hdr.time)
I have made some corrections in the query and it is working fine now:
SELECT hdr.date,hdr.time, LPAD(HOUR(hdr.time),2,'0') AS hour, COUNT(hdr.`order_id`) AS order_count, SUM(dtl.order_units) AS total_units, SUM((hdr.total_amount+hdr.round-hdr.discount)-hdr.refund) AS net_amount
FROM orders hdr
LEFT JOIN (
SELECT order_id, SUM(order_units) AS order_units
FROM order_details
WHERE is_cancelled=0 GROUP BY order_id) dtl ON dtl.order_id = hdr.order_id
WHERE DATE(hdr.date) = '2017-06-16 ' AND (HOUR(hdr.time) BETWEEN ('10') AND ('12'))
GROUP BY hdr.date, HOUR(hdr.time)
Thank you.

sql select query from two different tables WHERE active=1

i try select all columns from two different tables WHERE active = 1
i have 2 tables table_pro and table_basic,
sql:"select * from table_basic,table.name";
and 2 condition:
WHERE active = 1
WHERE table_pro.id = table_basic.name.id
how to make it correctly
Here is table_pro
+----+--------+---------+-----------+
| id | people | rooms | active |
+----+--------+---------+-----------+
| 1 | 5 | 10 | 0 |
| 2 | 12 | 17 | 0 |
| 3 | 21 | 38 | 1 |
+----+--------+---------+-----------+
Here is table_basic
+---------+-------+---------+------------+----------+
| name_id | name | balance | title | time |
+---------+-------+---------+------------+----------+
| 1 |shop | 100 | failed | 15:10:20 |
| 2 |factory| 75 | error | 15:10:20 |
| 3 |studio | 25 | timed_out | 15:10:20 |
+---------+-------+---------+------------+----------+
I'd like to have this output result only rows (from of all columns) with status active = 1
+-----+-------+----- --+--------+-------+----------+---------+--------+
| id | people| rooms | name |balance| title | time | active |
+-----+-------+--------+--------+-------+----------+---------+--------+
| 3 | 21 | 38 | studio |25 | timed_out| 15:10:20| 1 |
+-----+-------+--------+--------+-------+----------+---------+--------+
Thanks
SELECT A.id, A.people, A.rooms, B.name, B.balance, B.title, B.time, A.active
FROM
table_pro AS A
JOIN
table_basic AS B
ON
A.id = B.name_id
WHERE
A.id = 3
SELECT table_pro.*, table_basic.*
FROM table_pro
INNER JOIN table_basic
ON table_basic.name_id = table_pro.id
WHERE table_pro.active = 1

SQL Query to Sort the result according to maximum common results

I have a problem in making SQL query. I am making a small Search Engine in which the word to page mapping or indexes are kept like this.
Sorry I wasn't able to post images here so I tried writing the output like this.
+---------+---------+-----------+--------+
| word_id | page_id | frequency | degree |
+---------+---------+-----------+--------+
| 2331 | 29 | 2 | 1 |
| 2332 | 29 | 7 | 1 |
| 2333 | 29 | 4 | 1 |
| 2334 | 29 | 1 | 1 |
| 2335 | 29 | 1 | 1 |
| 2336 | 29 | 1 | 1 |
| 2337 | 29 | 2 | 1 |
| 2338 | 29 | 7 | 1 |
| 2343 | 29 | 1 | 3 |
| 2344 | 29 | 1 | 3 |
......
......
...... and so on.
Word_id points to Words present in other table and page_id points to URLs present in other table.
Now Suppose I want to search "Rapid 3D Prototyping Services". I brought the union of results corresponding to individual words by query ->
select * from words_detail where word_id=2353 or word_id=2364 or word_id=2709 or word_id=2710;
In above query the word_ids corresponds to the 4 words in the search query and the results are as below.
Union of page_id corresponding to individual words...
mysql>
select * from words_detail where word_id=2353 or word_id=2364 or word_id=2709 or word_id=2710;
+---------+---------+-----------+--------+
| word_id | page_id | frequency | degree |
+---------+---------+-----------+--------+
| 2353 | 29 | 2 | 4 |
| 2353 | 33 | 2 | 2 |
| 2353 | 36 | 5 | 9 |
| 2353 | 40 | 1 | 4 |
| 2353 | 41 | 1 | 9 |
| 2353 | 45 | 4 | 9 |
| 2353 | 47 | 2 | 9 |
| 2353 | 49 | 4 | 9 |
| 2353 | 52 | 1 | 4 |
| 2353 | 53 | 1 | 9 |
| 2353 | 66 | 2 | 9 |
| 2364 | 29 | 1 | 4 |
| 2364 | 34 | 1 | 4 |
| 2364 | 36 | 9 | 2 |
| 2709 | 36 | 1 | 9 |
| 2710 | 36 | 1 | 9 |
+---------+---------+-----------+--------+
16 rows in set (0.00 sec)
But I want the result to be sorted according to maximum match. The earlier result should be where all 4 words match, next result should be with 3 match and so on. In other words earlier results should have those page_id which are common to 4 word_ids, next should be those which are common in 3 words_ids and so on.
I checked here but this is not working in my case because in my case OR conditions are not matched in a single row.
How can such a query can be designed?
Use the occurence of you page_id as your matching count and then order by it.
select * from words_detail A
inner join
(SELECT PAGE_ID
, COUNT(PAGE_ID) matchCount
from words_detail
where word_id=2353 or word_id=2364 or word_id=2709 or word_id=2710
group by PAGE_ID) B
on A.PAGE_ID=B.PAGE_ID
where word_id=2353 or word_id=2364 or word_id=2709 or word_id=2710
order by matchCount desc
Try this
select p.*
from words_detail p
, (select word_id, count(1) as count
from words_detail where
word_id in (2353,2364,2709,2710) group by word_id) t
where p.word_id = t.word_id
order by t.count desc;
You can do a subquery to get the number of apperances for each page. Then you have to join the subquery with your table and you will be able to order the results by the number of page appearances.
Your final query should look like this:
SELECT *
FROM words_detail,
(
SELECT page_id,
COUNT(*) AS npages
FROM words_detail
WHERE word_id IN (2353, 2364, 2709, 2710)
GROUP BY page_id
) AS matches
WHERE words_detail.page_id = matches.page_id
AND word_id IN (2353, 2364, 2709, 2710)
ORDER BY matches.npages DESC