How to solve null value in MySQL? - c#

I want to show data separately from income and expense table in MySQL using same query for both things but it show me when show income title date then same show expense title date. But I need to do if it find income table's 4th row and if find expense table's 2nd row, but it show me 4th row. Why?
SELECT income.date,
IF(income.income_sourch IS NULL, 'N/A', income.income_sourch )as 'Income Title',
income.amount as 'income',
IF(expense.expense_sourche IS NULL, 'N/A', expense.expense_sourche) as 'ExpenseTitle',
expense.amount as 'Expense'
from expense RIGHT JOIN income
ON expense.date=income.date
where expense.date='30-Aug-2016'

Why - because that's how joins work when you have only a date to join the 2 tables. To solve this you need to create a relationship in addition to the date bearing in mind that at any one time the number of records in income could be greater than, less than or equal to the number of records in expenses. If we generate a row number for each row in income and independently generate a row number for each row in expenses then we can join income and expenses on row number
for example
/*
CREATE TABLE INCOME (ID INT,DESCRIPTION VARCHAR(10),DT DATE,AMOUNT INT);
INSERT INTO INCOME VALUES
(1,'SALE','2016-08-30',100),
(2,'ROKY','2016-08-30',200),
(3,'KORIM','2016-08-30',300),
(4,'SALEVOUCHR','2016-08-30',400);
CREATE TABLE EXPENSES (ID INT,DESCRIPTION VARCHAR(10),DT DATE,AMOUNT INT);
TRUNCATE TABLE EXPENSES;
INSERT INTO EXPENSES VALUES
(1,'RENT','2016-08-30',100),
(2,'UTILITIES','2016-08-30',100);
/*
This code
SELECT S.DT,S.DESCRIPTION,S.AMOUNT, s.rn,T.DESCRIPTION,T.AMOUNT, t.rn1
FROM
(
SELECT I.DT,I.DESCRIPTION,I.AMOUNT,
#RN:=#RN + 1 RN
FROM (SELECT #RN:=0) RN,INCOME I
) S
LEFT OUTER JOIN
(SELECT E.DT,E.DESCRIPTION,E.AMOUNT,
#RN1:=#RN1 + 1 RN1
FROM (SELECT #RN1:=0) RN1, EXPENSES E
) T ON T.RN1 = S.RN AND T.DT = S.DT
WHERE S.DT IS NOT NULL
results in
+------------+-------------+--------+------+-------------+--------+------+
| DT | DESCRIPTION | AMOUNT | rn | DESCRIPTION | AMOUNT | rn1 |
+------------+-------------+--------+------+-------------+--------+------+
| 2016-08-30 | SALE | 100 | 1 | RENT | 100 | 1 |
| 2016-08-30 | ROKY | 200 | 2 | UTILITIES | 100 | 2 |
| 2016-08-30 | KORIM | 300 | 3 | NULL | NULL | NULL |
| 2016-08-30 | SALEVOUCHR | 400 | 4 | NULL | NULL | NULL |
+------------+-------------+--------+------+-------------+--------+------+
BUT this is UNSAFE because it assumes that there are always more income than expense items
for example if we add 3 more expense rows
TRUNCATE TABLE EXPENSES;
INSERT INTO EXPENSES VALUES
(1,'RENT','2016-08-30',100),
(2,'UTILITIES','2016-08-30',100),
(3,'RATES','2016-08-30',100),(4,'SALARY','2016-08-30',100),(5,'INSURANCE','2016-08-30',100);
then the last expense item is lost resulting in
+------------+-------------+--------+------+-------------+--------+------+
| DT | DESCRIPTION | AMOUNT | rn | DESCRIPTION | AMOUNT | rn1 |
+------------+-------------+--------+------+-------------+--------+------+
| 2016-08-30 | SALE | 100 | 1 | RENT | 100 | 1 |
| 2016-08-30 | ROKY | 200 | 2 | UTILITIES | 100 | 2 |
| 2016-08-30 | KORIM | 300 | 3 | RENT | 100 | 3 |
| 2016-08-30 | SALEVOUCHR | 400 | 4 | UTILITIES | 100 | 4 |
+------------+-------------+--------+------+-------------+--------+------+
To cope with this we can simulate a full join like so
SELECT S.*,T.*
FROM
(
SELECT I.DT,I.DESCRIPTION,I.AMOUNT,
#RN:=#RN + 1 RN
FROM (SELECT #RN:=0) RN,INCOME I
) S
LEFT JOIN
(SELECT E.DT,E.DESCRIPTION,E.AMOUNT,
#RN1:=#RN1 + 1 RN1
FROM (SELECT #RN1:=0) RN1, EXPENSES E
) T ON T.RN1 = S.RN AND T.DT = S.DT
UNION
SELECT S.*,T.*
FROM
(
SELECT I.DT,I.DESCRIPTION,I.AMOUNT,
#RN3:=#RN3 + 1 RN3
FROM (SELECT #RN3:=0) RN3,INCOME I
) S
RIGHT JOIN
(SELECT E.DT,E.DESCRIPTION,E.AMOUNT,
#RN4:=#RN4 + 1 RN4
FROM (SELECT #RN4:=0) RN4, EXPENSES E
) T ON T.RN4 = S.RN3 AND T.DT = S.DT
result
+------------+-------------+--------+------+------------+-------------+--------+------+
| DT | DESCRIPTION | AMOUNT | RN | DT | DESCRIPTION | AMOUNT | RN1 |
+------------+-------------+--------+------+------------+-------------+--------+------+
| 2016-08-30 | SALE | 100 | 1 | 2016-08-30 | RENT | 100 | 1 |
| 2016-08-30 | ROKY | 200 | 2 | 2016-08-30 | UTILITIES | 100 | 2 |
| 2016-08-30 | KORIM | 300 | 3 | 2016-08-30 | RATES | 100 | 3 |
| 2016-08-30 | SALEVOUCHR | 400 | 4 | 2016-08-30 | SALARY | 100 | 4 |
| NULL | NULL | NULL | NULL | 2016-08-30 | INSURANCE | 100 | 5 |
+------------+-------------+--------+------+------------+-------------+--------+------+

you just need to add limits inside the query
if expense table limit 2
if other limit 4
See how to add limit to the query with if condition

Related

How to update stock table quantity on the basis of expiry date?

Hello everyone i have a table of inventory stock with columns as following
Item_ID | Expiry_Date | Quantity | Rate
cB0001 | 01-18-2021 | 5 | 150
cB0001 | 12-08-2020 | 3 | 145
cB0001 | 02-15-2021 | 25 | 155
Note : Rate is not an issue I just want to update the Stock Table Quantity on the basis on expiry date and available qty.
Now i want to sale inventory to customers of item cB0001 qty : 10 from the stock that expire first. Now the problem is that sale quantity is 10 and I want to minus the quantity 5 of expiry date 01-18-2021 and 3 From expiry date 12-08-2020 and 2 from 02-15-2021. Basically i want to implement FIFO logic using one query. I want to update the stock table quantity using this
update stock set quantity = quantity - '10' where item_id = 'cB0001' and expiry_Date < Now()
But this not giving accurate result. How to fix this problem? you have any idea?
I hope you understand my question
I assume you intend to do this in a trigger. So the 'trick' is to work out when the sale is fulfilled (working out IF it can be fulfilled is another issue). To do this allocate a value of 0 to rows where the cumulative quantity is less than the sale, 1 to the row where the sale can finally be fullfilled and 2 after that. I have assumed there is a unique row identifier to cope with multiple inventory entries for the same date - in my case inventory.id
drop table if exists inventory,sales;
create table inventory
(id int auto_increment primary key,Item_ID varchar(20), Expiry_Date date, Quantity int, Rate int);
create table sales (item_id varchar(20), quantity int);
insert into inventory values
( null,'cB0001' , str_to_date('01-18-2021','%m-%d-%Y'), 5 , 150),
( null,'cB0001' , str_to_date('12-08-2020','%m-%d-%Y'), 3 , 145),
( null,'cB0001' , str_to_date('02-15-2021','%m-%d-%Y'), 25 , 155),
( null,'cB0001' , str_to_date('02-15-2021','%m-%d-%Y'), 10 , 155),
( null,'cB0001' , str_to_date('02-15-2021','%m-%d-%Y'), 10 , 155),
( null,'cB0001' , str_to_date('02-15-2021','%m-%d-%Y'), 10 , 155),
( null,'cB0002' , str_to_date('02-15-2021','%m-%d-%Y'), 30 , 155);
drop trigger if exists t;
delimiter $$
create trigger t after insert on sales
for each row
begin
update inventory left join
(select s.*,
if(fst = 0, #runqty:=#runqty+quantity,#runqty:=#runqty) qty
from
(
select *,
#t:=#t+quantity cumqty,
if(#t>=#sale,if(#p>=1,2,#p:=1),#p:=0) fst
from inventory
cross join (select #t:=0,#p:=0,#sale:=new.quantity) t
where quantity > 0 and item_id = new.item_id
order by item_id,expiry_date
) s
cross join (select #runqty:=0) r
where fst in (0,1)
) a
on a.id = inventory.id
set inventory.quantity = case when fst = 0 then 0
when fst = 1 then inventory.quantity - (new.quantity - a.qty)
else inventory.quantity
end;
end $$
delimiter ;
MariaDB [sandbox]> insert into sales values('cb0001',10);
Query OK, 1 row affected (0.095 sec)
MariaDB [sandbox]> select * from inventory order by item_id,expiry_date;
+----+---------+-------------+----------+------+
| id | Item_ID | Expiry_Date | Quantity | Rate |
+----+---------+-------------+----------+------+
| 2 | cB0001 | 2020-12-08 | 0 | 145 |
| 1 | cB0001 | 2021-01-18 | 0 | 150 |
| 3 | cB0001 | 2021-02-15 | 23 | 155 |
| 4 | cB0001 | 2021-02-15 | 10 | 155 |
| 5 | cB0001 | 2021-02-15 | 10 | 155 |
| 6 | cB0001 | 2021-02-15 | 10 | 155 |
| 7 | cB0002 | 2021-02-15 | 30 | 155 |
+----+---------+-------------+----------+------+
7 rows in set (0.001 sec)
MariaDB [sandbox]>
MariaDB [sandbox]> insert into sales values('cb0001',25);
Query OK, 1 row affected (0.111 sec)
MariaDB [sandbox]>
MariaDB [sandbox]> select * from inventory order by item_id,expiry_date;
+----+---------+-------------+----------+------+
| id | Item_ID | Expiry_Date | Quantity | Rate |
+----+---------+-------------+----------+------+
| 2 | cB0001 | 2020-12-08 | 0 | 145 |
| 1 | cB0001 | 2021-01-18 | 0 | 150 |
| 3 | cB0001 | 2021-02-15 | 0 | 155 |
| 4 | cB0001 | 2021-02-15 | 8 | 155 |
| 5 | cB0001 | 2021-02-15 | 10 | 155 |
| 6 | cB0001 | 2021-02-15 | 10 | 155 |
| 7 | cB0002 | 2021-02-15 | 30 | 155 |
+----+---------+-------------+----------+------+
7 rows in set (0.001 sec)

Most efficient way to query for multiple rows and their specific sub-items (e.g. A `Sale` table and its `Items`)

I have the following tables:
Sales Table:
+----+------------+
| ID | Date |
+----+------------+
| 1 | 11/20/2018 |
| 2 | 11/21/2018 |
+----+------------+
Items Table:
+----+------------+----------+-------+----------+
| ID | FK_Sale_ID | Quantity | Price | Subtotal |
+----+------------+----------+-------+----------+
| 1 | 1 | 5 | 100 | 500 |
| 2 | 1 | 3 | 50 | 150 |
| 3 | 2 | 5 | 60 | 300 |
+----+------------+----------+-------+----------+
Currently, I query for the Sale rows and then run another query for each to retrieve all of its Items after which, I initialize them as objects in my C# Program. My problem is that I frequently run into scenarios where I'm dealing with hundreds of sales at the same time. Because of this, I have to run hundreds of queries as well.
My question is, is there a more efficient way to query for all Sales and their Items or is this it? I thought of trying a query like
SELECT *
FROM items_table
WHERE FK_Sale_ID = '1' OR FK_Sale_ID = '2'
And then manually sorting which Item belonged to which sale for initialization but this query quickly got messy after dealing with more than a few sales. Any ideas?
You can use join clause to combine multiple tables data in your query:
SELECT *
FROM items_table
JOIN sales_table ON items_table.FK_Sale_ID = sales_table.ID
WHERE sales_table.Date = #somedate
With this query when #somedate = 11/20/2018 you basically will get this data in one go:
+----+------------+----+------------+----------+-------+----------+
| ID | Date | ID | FK_Sale_ID | Quantity | Price | Subtotal |
+----+------------+----+------------+----------+-------+----------+
| 1 | 11/20/2018 | 1 | 1 | 5 | 100 | 500 |
| 1 | 11/20/2018 | 2 | 1 | 3 | 50 | 150 |
+----+------------+----+------------+----------+-------+----------+
Use SELECT items_table.* to get all fields of items table only

MYSQL - Rows to Columns using join statement

I have to get data from 2 tables using join.1st table Name is sliprecord
+-------+-----------+-----------------------+---------+
| cid | cname | date | totalAmount |
+-------+-----------+-----------------------+---------+
| 8 | Umer | 2015-12-15 | 1000 |
| 9 | Shakir | 2015-12-20 | 2000 |
+-------+-----------+-----------------------+---------+
Another table Name is expense
+-------+-----------+-----------------------+---------+
| idExpense | title | date | amount |
+-------+-----------+-----------------------+---------+
| 1 | BreakFast | 2015-12-15 | 300 |
| 2 | Lunch | 2015-12-15 | 500 |
| 3 | Dinner | 2015-12-17 | 700 |
+-------+-----------+-----------------------+---------+
I want to create balance sheet, If sliprecord Table don't have a date in expense Table then it should also give me sliprecord date and sliprecord totalAmount .
And If expense don't have a date in sliprecord Table then it should also give me expense title,expense date,and expense amount .
Desired Out put should be like this:
+-------+-----------+-----------------------+---------+
| title | EXP_date | amount | Slip_date | totalAmount
+-------+-----------+-----------------------+---------+
| BreakFast | 2015-12-15 | 300 |2015-12-15 | 1000
| Lunch | 2015-12-15 | 500 | |
| Dinner | 2015-12-17 | 700 |
| | | |2015-12-20 | 2000
+-------+-----------+-----------------------+---------+

ASP.net Linq to SQL grouping and adding at the same time?

I have a table of products
products:
ProdID | ProdName
1 | shirt
2 | pants
table of sizes:
SizeID | Size
1 | small
2 | med
3 | large
Table of orders
OrderID | ProdID | SizeID | Qty
1 | 1 | 1 | 4
2 | 1 | 1 | 3
3 | 1 | 2 | 2
4 | 2 | 1 | 1
5 | 2 | 3 | 1
How do I get results like this:
ProdName | Size | Total qty ordered (group by product and size add all quantities)
shirt | small | 7
shirt | med | 2
pants | small | 1
pants | large | 1
Thank you
from o in dc.Orders
group o by new { o.Product.ProdName, o.Size.Size } into g
select new { g.Key.ProdName, g.Key.Size, Total = g.Sum(or => or.Qty))};

Query database for multiple columns from a key value pair table

I am working on defining a sql query for use in sql server compact edition 3.5 on a windows mobile handset. I am going to need to get back a result set from three tables.
I don't exactly remember all the column names, as I'm asking this question at home, but here is a good example of the tables I'm dealing with.
Table 1: Customers
Table 2: PresoldOrders
Table 3: CustomerDetails
*
________________________________________
| |
|--------------- Customers --------------|
|________________________________________|
| |
| PK int CustomerNumber |
| varchar(125) FirstName |
| varchar(125) LastName |
| varchar(125) Email |
| varchar(200) Address1 |
| varchar(200) Address2 |
| varchar(200) City |
| varchar(2) State |
| varchar(5) Zip |
|________________________________________|
*
________________________________________
| |
|------------ CustomerDetails -----------|
|________________________________________|
| |
| PK int CustomerDetailsId |
| FK int CustomerNumber |
| varchar(255) FieldName |
| varchar(255) FieldValue |
|________________________________________|
*
________________________________________
| |
|------------ PresoldOrders -------------|
|________________________________________|
| |
| PK int PresoldOrderId |
| FK int CustomerNumber |
| int OrderNumber |
| int RouteStopNumber |
| datetime DeliveryDate |
| varchar(100) Other1 |
| varchar(100) Other2 |
|________________________________________|
Now, the query should return all records that exist in customers even if they don't exist in 'PresoldOrderHeaders' table. This part of it is pretty easy, I plan to just use a left outer join. The second part of the query is a bit more complex.
Here is the query I've constructed so far.
SELECT c.CustomerNumber
c.FirstName
c.LastName
c.Email
c.Address1
c.Address2
c.City
c.State
c.Zip
po.OrderNumber
po.DeliveryDate
po.Other1
po.Other2
FROM Customer c
LEFT OUTER JOIN PresoldOrders po on c.CustomerNumber = po.CustomerNumber
ORDER BY po.RouteStopNumber;
Tricky part is the CustomerDetails table. Here is an example of some data
_________________________________________________________
| | | | |
| PK | CustomerNumber | FieldName | FieldValue |
|-------|-----------------|--------------|----------------|
| 1 | 1 | A | 125 |
|-------|-----------------|--------------|----------------|
| 2 | 1 | B | 126 |
|-------|-----------------|--------------|----------------|
| 3 | 1 | C | 127 |
|-------|-----------------|--------------|----------------|
| 4 | 2 | A | 138 |
|-------|-----------------|--------------|----------------|
| 5 | 2 | B | 140 |
|-------|-----------------|--------------|----------------|
| 6 | 2 | C | 143 |
|-------|-----------------|--------------|----------------|
|_________________________________________________________|
For the information that I will be displaying in the Component One Flex Grid, the FieldName's listed in the CustomerDetails table will be fixed.
Here is want I want to archive:
_____________________________________________________________________________________________________________________
| | | | | | | |
| CustomerNumber | FirstName | LastName | ... | FieldName A's value | FieldName B's Value | FieldName C's Value |
|-----------------|-----------|----------|-----|---------------------|---------------------|--------------------------|
| 1 | John | Someone | ... | 125 | 126 | 127 |
|-----------------|-----------|----------|-----|---------------------|---------------------|--------------------------|
| 2 | Dan | Other | ... | 138 | 140 | 143 |
|-----------------|-----------|----------|-----|---------------------|---------------------|--------------------------|
|_____________________________________________________________________________________________________________________|
Normally, I'd have column names for A, B, and C defined in the 'CustomerDetails' table; however, this table can't be changed, so I must work with what I've been given. The requirements in the spec for my task is to have 15 plus columns to be displayed in a grid on a mobile device; not something I'd go for but those are the requirements.
Ok finally, the question:
Can one use sql to query a key value pairing table and have those key's value's displayed in columns like the above? This is the requirement I have and I'm thinking I'll need to create one query with my join on presoldorders table and then get a list of all details for each customer in a list and iterate through and combine into data table in code on handheld.
If you know in advance all key values, you can pivot resultset. I'm not sure if sql server compact supports PIVOT, but you can do:
select CustomerNumber,
Max(Case when FieldName='A' then FieldValue end) as a_value,
// the same for B, C, all keys.
From CustomerDetails
Group by CustomerNumber
For simplicity I don't join other tables, but I hope it gives you an idea how to turn rows into columns.

Categories