make the price of one line the price of all lines - mysql

I just started using mysql for SAP.
I would like to get this result:
DocEntry Description Price
00001 item A 100.00
00003 item C 110.00
From this data
DocEntry Description Quantity Price
00001 item A 2 300.00
00001 freight - 100.00
00002 item A 1 300.00
00003 item C 1 300.00
00003 freight - 110.00
I tried to filter the items with freight through this:
create view table_a
as
select DocEntry, Description, Price
from inv1 where Description like 'freight'
create view table_b
as
select DocEntry, Description, Price
from inv1
where exist (select * from table_a where table_a.DocEntry = table_b.DocEntry
I don't know though what to do with price?
Thanks!

It looks like you want the freight fit each item:
select distinct a.DocEntry, a.Description, b.Price
from inv1 a
join inv1 b on a.DocEntry = b.DocEntry
where a.Description != 'freight'
and b.Description = 'freight'
although the data does not require it, the distinct keyword has been added in case there are multiple "item" rows for each "freight" row. If the is no possibility of that ever happening, distinct may be removed.

It's not quite clear what you're asking, but maybe something like this...
DROP TABLE IF EXISTS my_table;
CREATE TABLE my_table
(DocEntry INT NOT NULL, Description VARCHAR(12) NOT NULL, Quantity INT NULL,Price INT NOT NULL,PRIMARY KEY(DocEntry,Description));
INSERT INTO my_table VALUES
(1,'item A',2,300),
(1,'freight',NULL,100),
(2,'item A',1,300),
(3,'item C',1,300),
(3,'freight',NULL,110);
mysql> SELECT * FROM my_table;
+----------+-------------+----------+-------+
| DocEntry | Description | Quantity | Price |
+----------+-------------+----------+-------+
| 1 | freight | NULL | 100 |
| 1 | item A | 2 | 300 |
| 2 | item A | 1 | 300 |
| 3 | freight | NULL | 110 |
| 3 | item C | 1 | 300 |
+----------+-------------+----------+-------+
SELECT docentry
, MAX(CASE WHEN description = 'freight' THEN price END) price
, MAX(CASE WHEN quantity IS NOT NULL THEN description END) description
FROM my_table
GROUP
BY docentry
HAVING price IS NOT NULL;
+----------+-------+-------------+
| docentry | price | description |
+----------+-------+-------------+
| 1 | 100 | item A |
| 3 | 110 | item C |
+----------+-------+-------------+

Related

Hash the result from the database , Is it possible?

I don't know if the question wording is correct or not, but I want to do the following:
I have a table named sales It contain following columns:
------------------------------------------------
| PRODUCT_NAME | PRODUCT_QUANTITY | ExpierDate |
------------------------------------------------
if I SELECT * FROM sales then the result will be :
------------------------------------------------
| PRODUCT_NAME | PRODUCT_QUANTITY | ExpierDate |
------------------------------------------------
| TestName | 5 | 2021-6-12 |
| TestName | 2 | 2024-10-18 |
------------------------------------------------
What I need to do is to select query and get the result look like this :
------------------------------------------------
| PRODUCT_NAME | PRODUCT_QUANTITY | ExpierDate |
------------------------------------------------
| TestName | 1 | 2021-6-12 |
| TestName | 2 | 2021-6-12 |
| TestName | 3 | 2021-6-12 |
| TestName | 4 | 2021-6-12 |
| TestName | 5 | 2021-6-12 |
| TestName | 1 | 2024-10-18 |
| TestName | 2 | 2024-10-18 |
------------------------------------------------
Is this even possible ?
How can I do this..!?
I would recommend directly using a recursive CTE:
with recursive cte as (
select product_name, product_quantity, expire_date, 1 as n
from sales s
union all
select product_name, product_quantity, expire_date, n + 1
from cte
where n < product_quantity
)
select *
from cte
order by product_name, product_quantity, expire_date, n;
Here is a db<>fiddle.
As I mention in comment, with cte create pseudo data to fill up the row is really easy:
with RECURSIVE quan(quantity) AS (
SELECT 1
UNION ALL
SELECT quantity+1 FROM quan WHERE quantity < 10 --you may have to increase this
)
SELECT tb.PRODUCT_NAME ,quan.quantity as PRODUCT_QUANTITY,tb.ExpierDate
FROM [tb] -- your result table
JOIN quan on tb.PRODUCT_QUANTITY >= quan.quantity
ORDER BY tb.time,quan.quantity
here is db<>fiddle with pseudo data.
using int column as time column in pseudo data but I think query itself will still work.
In recursive cte you may have to increase the where part to create more pseudo quantity data depend on your max quantity.

How to select sum of specific id in select query MySQL, Beego

I want to get a result like
result
-------------------------------------------------------
id | uuid | user_id |created_date | amount | name
-------------------------------------------------------
1 | ABC | 1 | 2019/5/1 | 5 | xa
2 | PQR | 2 | 2019/5/5 | 150 | xb
A query that I trying to use
SELECT(SELECT SUM(paid_amount) WHERE ID = t1.**HERE**) AS sub1,
(t1.amount - sub1) AS sub2
FROM invoice t1 CROSS JOIN
invoice_paid t2;
Table struct in my DB
table invoice_paid
------------------------------------
id | uuid | paid_date | paid_amount
------------------------------------
1 | ABC | 2019/5/1 | 15
2 | ABC | 2019/5/5 | 80
table invoice
-------------------------------------------------------
id | uuid | user_id |created_date | amount | name
-------------------------------------------------------
1 | ABC | 1 | 2019/5/1 | 100 | xa
2 | PQR | 2 | 2019/5/5 | 150 | xb
I can use sum only 1 condition like where id = 1 but how do I combine this query in select query with a join query.
I use beego(golang), MariaDB
You can use this query. It JOINs the invoice table to a derived table of SUMs of all the amounts paid per invoice from invoice_paid, subtracting that total from the invoice amount to get the outstanding amount:
SELECT i.id, i.uuid, i.user_id, i.created_date, i.amount - COALESCE(p.amount, 0) AS amount, i.name
FROM invoice i
LEFT JOIN (SELECT uuid, SUM(paid_amount) AS amount
FROM invoice_paid
GROUP BY uuid) p ON p.uuid = i.uuid
ORDER BY i.id
Output:
id uuid user_id created_date name amount
1 ABC 1 2019-05-01 00:00:00 xa 5
2 PQR 2 2019-05-05 00:00:00 xb 150
Demo on dbfiddle

Select * from 2 tables where CatergoryID's are 1

I've got these tables:
table : _newapp_shop_products_events
+-------+-----------+-----------+-------------------+
| EventID | categoryID | Price |
+-------+-----------+-----------+-------------------+
| 9050 | 1 | 15.00 |
| 5048 | 2 | 12.00 |
+-------+-----------+-----------+-------------------+
table : _newapp_shop_products_categories
+-------+-----------+-----------+-------------------+
| CategoryID | Category_Name | photo |
+-------+-----------+-----------+-------------------+
| 1 | Tickets | one.jpg |
| 2 | Voucher | two.jpg |
+-------+-----------+-----------+-------------------+
table : _newapp_shop_products_activitys
+-------+-----------+-----------+-------------------+
| ActivityID | categoryID | Price |
+-------+-----------+-----------+-------------------+
| 80 | 1 | 13.00 |
| 95 | 2 | 18.00 |
+-------+-----------+-----------+-------------------+
And these are linked by a relationship, categories -> events, categories -> activities.
I want to display events and activities (the Events and Activity Tables not the _newapp ones) in one list and only display the items from both tables with categoryID = 1 for example. How would I solve this?
I have tried to join them or select them both in a union, it returns the rows fine but the internal link within mysql is broken. when I click on the second result set from 'Activitys' the id is correct and the price but when i click the id to go to the corresponding id it gives 0 rows result as it generates the query: SELECT * FROM representin_nl_-_1.Events WHERE Id = 5 But that is the wrong table, it should search it in SELECT * FROM representin_nl_-_1._newapp_shop_products_activitys WHERE Id = 5 instead. Result: The first 9050 when i click it, it goes to the correct row but the ids after that are not found. Result:
You probably want a UNION
SELECT 'Event' AS Type, EventID AS Id, Price
FROM Events
WHERE CategoryId = 1
UNION ALL
SELECT 'Activity' AS Type, ActivityID AS Id, Price
FROM Activity
WHERE CategoryId = 1
What do you mean Id conflict? You could do something like this instead
SELECT EventID, null AS ActivityId, Price
FROM Events
WHERE CategoryId = 1
UNION ALL
SELECT null, ActivityID, Price
FROM Activity
WHERE CategoryId = 1

How to enhance my subquery with two tables to search with 3 tables if the main table have 2 primary keys?

The main table is 'M_Order' which contains orders and its details
M_order
row_id |Order_Num | Order_Status | created | created_by | Account_ID
--------------------------------------------------------------
1-a | 1 | complete | 2016-08-25 | jhon | 3-a
1-b | 2 | pending | 2016-08-26 | mike | 3-b
1-c | 3 | failed | 2015-08-27 | mike | 3-c
1-d | 4 | pending | 2015-08-25 | jhon | 3-d
1-e | 5 | failed | 2016-08-26 | mike | 3-e
1-f | 6 | New | 2017-03-27 | jhon | 3-f
The 2nd table is 'Order_itmes' which contain lists of products for each order
Order_itmes
row_id |Order_id | Product_ID
--------------------------------------------------------------
2-a | 1-a | Prod_1
2-b | 1-b | Prod_2
2-c | 1-c | Prod_1
2-d | 1-d | Prod_1
2-e | 1-e | Prod_1
2-f | 1-f | Prod_3
The row_id from 'M_order' table is unique and available in the table 'Order_items' as Order_id
I have a query which show the orders with specific product_id from 'Order_items'
Select Order_Num,Order_status,created ,created_by
from M_order where row_id in (select Order_id from Order_itmes where
Product_ID='Prod_1')
where Order_Status='Failed'
Order By created desc
If I have a 3rd table 'Accounts' which having column row_id as the same column in account_id from 'M_Order'
Accounts
row_id | Name
--------------------------------------------------------------
3-a | cutomer1
3-b | cutomer2
3-c | cutomer3
3-d | cutomer4
3-e | cutomer5
3-f | cutomer6
how can I enhance the above query to list the customer name in results and shows as the following
Order_Num | Order_status | created | created_by | name
-------------------------------------------------------------
5 | failed |2016-08-26 | mike | customer5
3 | failed |2015-08-27 | mike | customer3
I believe it's better to use JOIN in this case as sub queries will get complicated once we have more than 2 tables. A simple JOIN would work here, e.g.:
SELECT o.order_num, o.order_status, o.created, o.created_by, a.name
FROM m_order o JOIN order_items oi ON o.row_id = oi.order_id
JOIN accounts a ON o.account_id = a.row_id
WHERE oi.product_id = 'Prod_1';
You can add a join to Accounts
select o.Order_Num, o.Order_status, o.created, o.created_by, a.name
from M_order o
inner join Accounts a
on o.Account_ID = a.row_id
where o.row_id in (
select Order_id
from Order_items
where Product_ID='Prod_1'
)
and o.Order_Status='Failed'
order by o.created desc
How can table have 2 PK ?
I am not commenting on index becasue you hv posted the real table structure and real data type.
Wht is the purpose of IDs as 1-a or 2-a or 3-a ?
Table should auto increament id as CI.
Also Order table contain million of record so you can't simply query any thing without using paging.
Try this,
declare #M_order table(row_id varchar(30),Order_Num int,Order_Status varchar(30)
,created date,created_by varchar(30),Account_ID varchar(30))
insert into #M_order VALUES
('1-a',1,'complete','2016-08-25','jhon','3-a')
,('1-b',2,'pending','2016-08-26','mike','3-b')
,('1-c',3,'failed','2015-08-27','mike','3-c')
,('1-d',4,'pending','2015-08-25','jhon','3-d')
,('1-e',5,'failed','2016-08-26','mike','3-e')
,('1-f',6,'New ','2017-03-27','jhon','3-f')
declare #Order_itmes table(row_id varchar(30),Order_id varchar(30), Product_ID varchar(30))
insert into #Order_itmes VALUES
('2-a','1-a','Prod_1'),('2-b','1-b','Prod_2'),('2-c','1-c','Prod_1')
,('2-d','1-d','Prod_1'),('2-e','1-e','Prod_1'),('2-f','1-f','Prod_3')
declare #Accounts table(row_id varchar(30),Name varchar(30))
insert into #Accounts values
('3-a','cutomer1') ,('3-b','cutomer2') ,('3-c','cutomer3')
,('3-d','cutomer4') ,('3-e','cutomer5') ,('3-f','cutomer6')
select mo.Order_Num ,mo.Order_status , mo.created , mo.created_by ,name
from #M_order MO
inner join #Accounts A
on mo.Account_ID=a.row_id
where Order_status='failed'
and
exists(
select Order_id from #Order_itmes OI where
Product_ID='Prod_1' and oi.Order_id=mo.row_id
)

using HAVING to filter results based on a reference row

I have the following table:
+---------+--------------+----------+
| item_id | location_id | price |
+---------+--------------+----------+
| 1 | 1 | 100 |
| 1 | 1 | 250 |
| 1 | 2 | 50 |
| 2 | 1 | 250 |
| 2 | 1 | 1000 |
| 3 | 1 | 1000 |
| 3 | 2 | 100 |
+---------+--------------+----------+
I can reduce this down to the minimum values using this query
SELECT
item_id, location_id, MIN(price) AS Price
from
table
GROUP BY item_id , location_id
This gets me
+---------+--------------+----------+
| item_id | location_id | price |
+---------+--------------+----------+
| 1 | 1 | 100 |
| 1 | 2 | 50 |
| 2 | 1 | 250 |
| 3 | 1 | 1000 |
| 3 | 2 | 100 |
+---------+--------------+----------+
I want to reduce this further. I am using the rows with a location_id of 1 as a reference row. For each row that has an item_id matching the reference row's item_id but a different location id. I want to compare that row's price with the reference row's price. If the price is lower than the reference row's price, I want to filter that row out.
My final result should include the reference row for each item id and any rows that met the criteria of the price being lower than the reference row price.
I have a hunch that I can use the HAVING clause to do this but I am having trouble compiling the statement. How should I construct the HAVING statement?
Thanks in advance
Nah, having can't help you like this, having is for things like you need filter min() result for something
e.g:
select id,min(price) from table where date = '2016-3-18' group by id having min(price) = 50
it will show you the records that min(price)=50
let's back to your case, there are lots of way to do that,
1. left join
select a.item_id,a.location_id,a.price
from table a
left join table b
on a.location_id = b.location_id and a.price > b.price
where b.price is null
2. exists
select a.item_id,a.location_id,a.price
from table a
where exists(
select 1 from
(select location_id,min(price)as price from table group by location_id)b
where a.location_id = b.location_id and a.price = b.price
)
normally i ll recommand you use exists