Mysql multiple order, one order by date with condition - mysql

I have a simple SQL request which orders the result by the number of sales and then by the number of views.
SELECT io__image.sales, io__image.viewcount, io__image.date
FROM io__image
ORDER BY io__image.sales DESC,
io__image.viewcount DESC;
But I would like the new images with a date greater than for example "2022-05-01" to appear just after the ones that have been sold.
Is it possible to have multiple order and in one of this order a condition?
ORDER BY io__image.sales DESC,
if(io_image.date >= "2022-05-01") ...,
io__image.viewcount DESC;
Example of current results:
+-------+-----------+---------------------+
| sales | viewcount | date |
+-------+-----------+---------------------+
| 5 | 7 | 2021-04-21 19:13:21 |
| 4 | 186 | 2018-05-09 13:45:40 |
| 4 | 135 | 2018-05-11 17:22:30 |
| 3 | 157 | 2018-05-02 09:47:48 |
| 1 | 8 | 2021-08-29 11:22:55 |
| 1 | 7 | 2021-06-21 12:26:32 |
| 1 | 5 | 2021-06-21 12:40:38 |
| 1 | 4 | 2021-06-14 15:15:01 |
| 0 | 824 | 2021-04-21 22:12:48 |
| 0 | 430 | 2020-11-27 13:46:59 |
| 0 | 228 | 2017-10-24 09:05:40 |
| 0 | 209 | 2019-11-24 11:32:43 |
| 0 | 184 | 2018-05-02 21:26:40 |
| 0 | 174 | 2018-05-02 21:21:20 |
| 0 | 174 | 2018-05-03 09:08:53 |
| 0 | 171 | 2018-05-02 09:20:34 |
Let's say we have 2 new images with a date >= 2022-05-01 with low viewcount and no sales, and I would like:
+-------+-----------+---------------------+
| sales | viewcount | date |
+-------+-----------+---------------------+
| 5 | 7 | 2021-04-21 19:13:21 |
| 4 | 186 | 2018-05-09 13:45:40 |
| 4 | 135 | 2018-05-11 17:22:30 |
| 3 | 157 | 2018-05-02 09:47:48 |
| 1 | 8 | 2021-08-29 11:22:55 |
| 1 | 7 | 2021-06-21 12:26:32 |
| 1 | 5 | 2021-06-21 12:40:38 |
| 1 | 4 | 2021-06-14 15:15:01 |
| 0 | 10 | 2022-07-14 12:11:25 |
| 0 | 5 | 2022-06-21 08:45:43 |
| 0 | 824 | 2021-04-21 22:12:48 |
| 0 | 430 | 2020-11-27 13:46:59 |
| 0 | 228 | 2017-10-24 09:05:40 |
| 0 | 209 | 2019-11-24 11:32:43 |
| 0 | 184 | 2018-05-02 21:26:40 |
| 0 | 174 | 2018-05-02 21:21:20 |
| 0 | 174 | 2018-05-03 09:08:53 |
| 0 | 171 | 2018-05-02 09:20:34 |

You can use the boolean expression sales = 0 AND date >= '2022-05-01' in the ORDER BY clause, between the 2 columns:
SELECT *
FROM io__image
ORDER BY sales DESC,
sales = 0 AND date >= '2022-05-01' DESC,
viewcount DESC;
See the demo.

Related

Query the differences between records with same ID

I have a table like this in MS Access 2019:
+-----------+------------+--------+----------+-------+
| BillingID | Date | RoomID | Electric | Water |
+-----------+------------+--------+----------+-------+
| 1 | 12/23/2018 | 4 | 1669 | 106 |
| 2 | 12/26/2018 | 1 | 5035 | 289 |
| 3 | 12/27/2018 | 6 | 0 | 0 |
| 4 | 12/31/2018 | 5 | 3158 | 223 |
| 5 | 1/6/2019 | 2 | 3823 | 194 |
| 6 | 1/15/2019 | 3 | 1772 | 125 |
| 7 | 1/23/2019 | 4 | 1796 | 117 |
| 8 | 1/26/2019 | 1 | 5231 | 299 |
| 9 | 1/27/2019 | 6 | 0 | 0 |
| 10 | 1/31/2019 | 5 | 3366 | 242 |
| 11 | 2/14/2019 | 2 | 3975 | 201 |
| 12 | 2/15/2019 | 3 | 1839 | 129 |
+-----------+------------+--------+----------+-------+
I could calculate the electricity and water usage with Index & Match in MS Excel. However, I've had a lot of trouble to achieve this with MS Access. The result I want is as below:
+-----------+------------+--------+----------+---------------+-------+------------+
| BillingID | Date | RoomID | Electric | ElectricUsage | Water | WaterUsage |
+-----------+------------+--------+----------+---------------+-------+------------+
| 1 | 12/23/2018 | 4 | 1669 | | 106 | |
| 2 | 12/26/2018 | 1 | 5035 | | 289 | |
| 3 | 12/27/2018 | 6 | 0 | | 0 | |
| 4 | 12/31/2018 | 5 | 3158 | | 223 | |
| 5 | 1/6/2019 | 2 | 3823 | | 194 | |
| 6 | 1/15/2019 | 3 | 1772 | | 125 | |
| 7 | 1/23/2019 | 4 | 1796 | 127 | 117 | 11 |
| 8 | 1/26/2019 | 1 | 5231 | 196 | 299 | 10 |
| 9 | 1/27/2019 | 6 | 0 | | 0 | |
| 10 | 1/31/2019 | 5 | 3366 | 208 | 242 | 19 |
| 11 | 2/14/2019 | 2 | 3975 | 152 | 201 | 7 |
| 12 | 2/15/2019 | 3 | 1839 | 67 | 129 | 4 |
+-----------+------------+--------+----------+---------------+-------+------------+
For example, for RoomID = 4, the ElectricUsage is the difference between the Electric in BillingID #7 and BillingID #1 and so on.
I've tried some answer like this or this but Access ran into errors when using those solutions in SQL view (Syntax error in FROM clause).
Thanks.
You can use a couple of sub-queries to return the Electric/Water for each room on the previous date:
SELECT
B.BillingID, B.BillingDate, B.RoomID, B.Electric,
B.Electric-(SELECT TOP 1 E.Electric FROM tblBilling AS E WHERE B.RoomID=E.RoomID AND E.BillingDate<B.BillingDate ORDER BY E.BillingDate DESC) AS ElectricUsage,
B.Water,
B.Water-(SELECT TOP 1 W.Water FROM tblBilling AS W WHERE B.RoomID=W.RoomID AND W.BillingDate<B.BillingDate ORDER BY W.BillingDate DESC) AS WaterUsage
FROM tblBilling AS B
Note that I've renamed your Date field to be BillingDate, as Date is a reserved word in Access, and will cause you problems in the future.
Regards,

Calculate sum, counts in many to many

Greetings I am trying to sum up expense value for each transaction.
Association table.
**Assoc table schema**
| PK_id | FK_transaction | FK_Expense |
|-------|----------------|------------|
| 1 | 1 | 85 |
| 2 | 2 | 81 |
| 3 | 3 | 77 |
| 4 | 4 | 83 |
| 5 | 5 | 84 |
| 6 | 6 | 105 |
| 7 | 7 | 104 |
| 8 | 8 | 71 |
| 9 | 8 | 88 |
| 10 | 8 | 90 |
Transaction table
**Transaction table schema**
| PK_id | type | value | confirmed_value |
|-------|------|-------|--------------------|
| 1 | 1 | 3.2 | 0 |
| 2 | 1 | 23.2 | 0 |
| 3 | 1 | 33.2 | 0 |
| 4 | 1 | 43.2 | 11.00 |
| 5 | 1 | 53.2 | 0 |
| 6 | 1 | 63.2 | 0 |
| 7 | 1 | 73.2 | 0 |
| 8 | 1 | 83.2 | 66.00 |
| 9 | 1 | 93.2 | 0 |
| 10 | 1 | 133.2 | 77.00 |
| 11 | 1 | 123.2 | 0 |
Expences Table
| PK_id | value |
|-------|-------|
| 85 | 3.2 |
| 81 | 23.2 |
| 77 | 33.2 |
| 83 | 43.2 |
| 84 | 53.2 |
| 105 | 63.2 |
| 104 | 73.2 |
| 71 | 83.2 |
| 88 | 93.2 |
| 90 | 133.2 |
Result ::
| PK_id | value | confirmed_value |
|-------|-------|-----------------|
| 1 | 3.2 | 0 |
| 2 | 23.2 | 0 |
| 3 | 33.2 | 0 |
| 4 | 43.2 | 11 |
| 5 | 53.2 | 0 |
| 6 | 63.2 | 0 |
| 7 | 73.2 | 0 |
| 8 | 83.2 | 66 |
| 8 | 93.2 | 66 |
| 8 | 133.2 | 66 |
Desired - before calculations ( just to give u the idea )
| PK_id | value | confirmed_value |
|-------|-------|-----------------|
| 1 | 3.2 | 0 |
| 2 | 23.2 | 0 |
| 3 | 33.2 | 0 |
| 4 | 43.2 | 11 |
| 5 | 53.2 | 0 |
| 6 | 63.2 | 0 |
| 7 | 73.2 | 0 |
| 8 | 309.6 | 66 |
Full desired result
count matching values COUNT(confirmed_value = value )
count entries that not match COUNT(confirmed_value != value )
/\ Calculate value of confirmed values
?? sum(transactions.confirmed_value)
and calculate value itself
Should be a row result ( example )
=======================================================================================================================
MATCHED | NOT_MATCHED | SUM(of values) | COUNT(of confirmed equal to value ) | COUNT(of confirmed ! equal to value )
=======================================================================================================================
1 | 10 | 3003.22 | 3 | 10
=======================================================================================================================
SQL Fiddle : http://sqlfiddle.com/#!9/2ab102/9
Thanks for any tips
Try this query -
SELECT transactions.PK_id,
SUM(expenses.value),
transactions.confirmed_value
FROM `assoc`
JOIN `expenses` ON `assoc`.`FK_Expense` = `expenses`.`PK_id`
JOIN `transactions` ON `assoc`.`FK_transaction` = `transactions`.`PK_id`
GROUP BY transactions.PK_id,
transactions.confirmed_value
Fiddle Demo - http://sqlfiddle.com/#!9/2ab102/14

SQL joining three tables and split into columns

I have three tables, mess_stock, mess_voucher, add_grocery.
Mess_stock table is below,
+-----+------------+-----------------+-----------------+--------+---------+---------+------------+----------+
| sno | voucher_id | particular_name | opening_balance | inward | outward | balance | pay_amount | pay_type |
+-----+------------+-----------------+-----------------+--------+---------+---------+------------+----------+
| 49 | 5 | 4 | 100 | 10 | 100 | 10 | 10.00 | 1 |
| 50 | 17 | 5 | 111 | 10 | 20 | 101 | 60.00 | 1 |
| 51 | 7 | 3 | 123 | 2 | 1 | 124 | 300.00 | 1 |
| 52 | 7 | 1 | 123 | 20 | 20 | 123 | 500.00 | 2 |
| 53 | 14 | 8 | 100 | 5 | 95 | 10 | 60.00 | 2 |
+-----+------------+-----------------+-----------------+--------+---------+---------+------------+----------+
Mess_voucher table is below
+------------+--------------+--------------+
| voucher_id | voucher_name | voucher_date |
+------------+--------------+--------------+
| 5 | VG1001 | 2015-02-19 |
| 6 | VG1001 | 2015-02-20 |
| 7 | VG1002 | 2015-02-20 |
| 8 | VG1002 | 2015-02-19 |
| 9 | MS1001 | 2015-02-20 |
| 10 | VG10012 | 2015-02-19 |
| 11 | 0 | 2015-02-23 |
| 12 | 1 | 2015-02-24 |
| 13 | MS1001 | 2015-02-25 |
| 14 | MS1001 | 2015-02-28 |
| 15 | VG1003 | 2015-02-28 |
| 16 | MS1001 | 2015-02-19 |
| 17 | MS1001 | 2015-02-21 |
+------------+--------------+--------------+
Add_grocery table is below
+-----+-----------------+------------------+
| sno | particular_name | particular_price |
+-----+-----------------+------------------+
| 1 | Rice | 25.00 |
| 3 | Mango | 150.00 |
| 4 | Coconut | 22.00 |
| 5 | Banana | 6.00 |
| 6 | Raddish | 12.00 |
| 7 | Apple | 150.00 |
| 8 | Pumkin | 12.00 |
+-----+-----------------+------------------+
I want to group the sum of pay_amount of mess_stock table. I have used the below query
SELECT opening_balance AS ope_stock,
balance AS clo_stock,
SUM(IF(pay_type = 1, pay_amount, 0)) mess_pay,
SUM(IF(pay_type=2, pay_amount, 0)) est_pay
FROM mess_stock;
That works fine. The particular_name is the auto increment id of add_grocery table. I need the inward outward amount total. For example the inward amount 10 means it has to get the particular_price from add_grocery using the particular_name provided in the mess_stock table, similarly I need all the answer. And I want to sort that by date wise. The date of the entry is stored in the mess_voucher table that is connected to mess_stock table.
Try this it will work :
Use Inner Join :
SELECT t2.`particular_name`,t1.`inward`,t1.`outward`,t2.`particular_price`,t3.`voucher_date` from Mess_stock t1 JOIN Add_grocery t2 ON t1.`particular_name`=t2.`sno` JOIN Mess_voucher t3 ON t3.`voucher_id`=t1.`voucher_id` ORDER BY t3.`voucher_date` DESC

MySQL Query to track transaction from 5 tables

I have 3 tables in my db, the scenario is inventory is entered into the database with reference to invoice no/po number, then users request for inventory and admin assign the items from specific invoices_items/po_items.
I need query to get when an invoice number is entered into the database and what quantity of items is this invoice has. then when when admin issue items from this issue. in other words i have to tracked inventory transactions with reference to invoice/po number.
I have following structure of tables,
table - po_reference
+----------------+-------------------------+--------------------+--------+---------------------+
| po_refrence_id | po_reference_name | requested_quantity | cost | created_on |
+----------------+-------------------------+--------------------+--------+---------------------+
| 6 | Dell Computer 000001256 | 14 | 15000 | 2015-02-18 10:36:33 |
| 11 | Dell Computer 000001257 | 50 | 150000 | 2015-02-18 10:38:33 |
+----------------+-------------------------+--------------------+--------+---------------------+
table - po_reference_details
+-------------------------+----------------+--------------------+-------------------+----------------------+-----------------------+
| po_reference_details_id | po_refrence_id | quantity_requested | quantity_received | quantity_outstanding | remarks |
+-------------------------+----------------+--------------------+-------------------+----------------------+-----------------------+
| 6 | 6 | 20 | 14 | 6 | 6 items are short.... |
| 8 | 11 | 60 | 50 | 10 | 10 items are short... |
+-------------------------+----------------+--------------------+-------------------+----------------------+-----------------------+
table - stock
+----------+----------+---------------------+------------+---------------------+------------+-----------+---------+--------------+---------+-------------+----------------+------------------+
| stock_id | quantity | created_on | created_by | updated_on | updated_by | module_id | item_id | main_unit_id | unit_id | category_id | po_refrence_id | startup_quantity |
+----------+----------+---------------------+------------+---------------------+------------+-----------+---------+--------------+---------+-------------+----------------+------------------+
| 290 | 35 | 2015-02-18 02:15:00 | NULL | NULL | NULL | 1 | 286 | 94 | 24 | 47 | 6 | 50 |
| 291 | 110 | 2015-02-18 00:00:00 | NULL | 2015-02-18 00:00:00 | NULL | 2 | 286 | 94 | 24 | 47 | 6 | 10 |
+----------+----------+---------------------+------------+---------------------+------------+-----------+---------+--------------+---------+-------------+----------------+------------------+
and request_stock_bridge
+--------------------------+------------+----------------+------------------+---------------------+--------------------------------------------------------------------+-----------------+--------------+
| stock_requests_bridge_id | request_id | po_refrence_id | quantity_on_hand | issued_date | remarks | issued_quantity | main_unit_id |
+--------------------------+------------+----------------+------------------+---------------------+--------------------------------------------------------------------+-----------------+--------------+
| 8 | 78 | 6 | 44 | 2015-02-18 06:49:34 | items are short , giving you 2 less, request after a week again... | 6 | 94 |
| 9 | 79 | 6 | 42 | 2015-02-18 08:18:56 | test | 2 | 94 |
| 10 | 80 | 6 | 35 | 2015-02-18 08:56:39 | 2 shorts.... | 7 | 94 |
+--------------------------+------------+----------------+------------------+---------------------+--------------------------------------------------------------------+-----------------+--------------+
and finally table - request
+------------+---------------+--------------------+---------------------+-----------------+--------+---------------+-----------+---------+
| request_id | department_id | quantity_requested | requested_date | quantity_issued | status | employee_name | module_id | item_id |
+------------+---------------+--------------------+---------------------+-----------------+--------+---------------+-----------+---------+
| 76 | 54 | 8 | 2015-02-18 00:00:00 | 0 | 0 | MTaqi | 2 | 279 |
| 77 | 54 | 7 | 2015-02-18 00:00:00 | 0 | 0 | MTaqi | 2 | 279 |
| 78 | 54 | 8 | 2015-02-18 00:00:00 | 0 | 1 | MTaqi | 2 | 286 |
| 79 | 54 | 2 | 2015-02-18 00:00:00 | 0 | 1 | MTaqi | 2 | 286 |
| 80 | 54 | 9 | 2015-02-18 00:00:00 | 0 | 1 | MTaqi | 2 | 286 |
+------------+---------------+--------------------+---------------------+-----------------+--------+---------------+-----------+---------+
i have write this query but doesn't work,
SELECT s.created_on, po.po_reference_name, s.startup_quantity, su.issued_date, su.issued_quantity, su.quantity_on_hand, su.remarks,po.po_refrence_id
FROM stock s, po_reference po, request r, stock_requests_bridge su
WHERE po.po_refrence_id = s.po_refrence_id
AND su.po_refrence_id = s.po_refrence_id
AND s.item_id = 286
GROUP by po.po_refrence_id
it returns this,
+---------------------+-------------------------+------------------+---------------------+-----------------+------------------+--------------------------------------------------------------------+----------------+
| created_on | po_reference_name | startup_quantity | issued_date | issued_quantity | quantity_on_hand | remarks | po_refrence_id |
+---------------------+-------------------------+------------------+---------------------+-----------------+------------------+--------------------------------------------------------------------+----------------+
| 2015-02-18 02:15:00 | Dell Computer 000001256 | 50 | 2015-02-18 06:49:34 | 6 | 44 | items are short , giving you 2 less, request after a week again... | 6 |
+---------------------+-------------------------+------------------+---------------------+-----------------+------------------+--------------------------------------------------------------------+----------------+

Update MySQL Query that selects records with a certain non-unique value

I'm looking for help creating a MySQL query. I have the following database table:
+----------------+-----------+-------------+------------+-------------------+---------+-------------+---------------+--------+
| option_type_id | option_id | sku | sort_order | customoptions_qty | default | in_group_id | dependent_ids | weight |
+----------------+-----------+-------------+------------+-------------------+---------+-------------+---------------+--------+
| 552 | 137 | 13071727 | 1000 | 0 | 0 | 0 | | 0.0000 |
| 553 | 137 | 13071727B | 1000 | 0 | 0 | 1 | | 0.0000 |
| 554 | 137 | 13071727C | 1000 | 1 | 0 | 2 | | 0.0000 |
| 555 | 137 | 13071727D | 1000 | 1 | 0 | 3 | | 0.0000 |
| 556 | 138 | 13085350-1 | 1000 | 0 | 0 | 0 | | 0.0000 |
| 557 | 138 | 13085350-1D | 1000 | 2 | 0 | 1 | | 0.0000 |
| 558 | 138 | 13085350-1C | 1000 | 3 | 0 | 2 | | 0.0000 |
| 559 | 138 | 13085350-1B | 1000 | 2 | 0 | 3 | | 0.0000 |
| 560 | 139 | 13069547M | 1000 | 20 | 0 | 0 | | 0.0000 |
| 561 | 140 | 13084477-2 | 950 | 2 | 0 | 0 | | 0.0000 |
| 562 | 140 | 13084477-2B | 951 | 2 | 0 | 1 | | 0.0000 |
| 563 | 140 | 13084477-2C | 952 | 3 | 0 | 2 | | 0.0000 |
| 564 | 140 | 13084477-2D | 953 | 0 | 0 | 3 | | 0.0000 |
| 565 | 140 | 13084477-2E | 954 | 2 | 0 | 4 | | 0.0000 |
| 566 | 141 | 13066533-1 | 1000 | 4 | 0 | 0 | | 0.0000 |
| 567 | 141 | 13066533-1B | 1000 | 5 | 0 | 1 | | 0.0000 |
| 568 | 141 | 13066533-1C | 1000 | 5 | 0 | 2 | | 0.0000 |
| 569 | 141 | 13066533-1D | 1000 | 0 | 0 | 3 | | 0.0000 |
| 570 | 142 | 13071674 | 1000 | 0 | 0 | 0 | | 0.0000 |
| 571 | 142 | 13071674D | 1000 | 1 | 0 | 1 | | 0.0000 |
| 572 | 142 | 13071674C | 1000 | 2 | 0 | 2 | | 0.0000 |
| 573 | 142 | 13071674B | 1000 | 0 | 0 | 3 | | 0.0000 |
| 574 | 142 | 13071674E | 1000 | 4 | 0 | 4 | | 0.0000 |
| 575 | 143 | 13071667 | 1000 | 0 | 0 | 0 | | 0.0000 |
| 576 | 143 | 13071667B | 1000 | 0 | 0 | 1 | | 0.0000 |
| 577 | 143 | 13071667C | 1000 | 0 | 0 | 2 | | 0.0000 |
| 578 | 143 | 13071667D | 1000 | 0 | 0 | 3 | | 0.0000 |
| 579 | 143 | 13071667E | 1000 | 0 | 0 | 4 | | 0.0000 |
| 580 | 144 | 13066295 | 1000 | 1 | 0 | 0 | | 0.0000 |
+----------------+-----------+-------------+------------+-------------------+---------+-------------+---------------+--------+
What I'd like to do is update all the rows where in_group_id = 0, to add an A to the end of the sku. However I'd only like to do this on rows that do not have a unique option_id value.
For example, you can see that the row with option_id = 139 is the only row with this option_id value, so I'd like to exclude this row from being updated.
Basically this is a list of product options, some products have multiple options each with it's own SKU. However for these products that have multiple options there is an 'A' missing from the end of the 1st option's SKU, and I'd like to add it. But I don't wish to add an 'A' to products that only have 1 option. I hope this makes sense.
If someone could advise on the MySQL statement that could achieve this, that would be great!
This query will do what you want :
UPDATE Table1
LEFT OUTER JOIN (SELECT *
FROM Table1
GROUP BY option_id
HAVING count(*) = 1) t1 ON t1.option_type_id = Table1.option_type_id
SET table1.sku = concat(table1.sku,'A')
WHERE table1.in_group_id = 0 AND t1.option_type_id is null
See SQL FIDDLE : http://www.sqlfiddle.com/#!2/9d08e/1/0
You can use a sub-query to limit to only those option_ids that have a count of 1.
UPDATE YourTable T
INNER JOIN
(SELECT option_id
,COUNT(option_id) as opt_count
FROM YourTable T1
GROUP BY
option_id
) SQ
ON SQ.option_id = T.option_id
SET T.sku = CONCAT(T.sku,'A')
WHERE T.in_group_id = 0
AND SQ.opt_count = 1