I'm trying to do some SQL in C# along with an Access Database. I have two tables. Main Table and a Second Table:
MAIN TABLE
DoubleValue | | | |
----------------------------------------
1,40 | | | |
1,80 | | | |
2,00 | | | |
1,80 | | | |
1,60 | | | |
1,60 | | | |
----------------------------------------
SECOND TABLE
DoubleValue | Points | Weight |
-------------------------------
1,00 | 100 | 2 |
1,20 | 98 | 2 |
1,40 | 96 | 2 |
1,60 | 94 | 2 |
1,80 | 92 | 2 |
2,00 | 90 | 2 |
-------------------------------
I need to find all matching rows in "SECOND TABLE" based on the column "Double Value". Then for the rows that matches I want to get the value in columns "Points" and "Weight" as well as multplie those two columns and create a columns with the name "Sum" and add all three columns to the "MAIN TABLE":
MAIN TABLE - RESULT/OUTPUT
DoubleValue | Points | Weight | Sum |
-------------------------------------
1,40 | 96 | 2 | 192 |
1,80 | 92 | 2 | 184 |
2,00 | 90 | 2 | 180 |
1,80 | 92 | 2 | 184 |
1,60 | 94 | 2 | 188 |
1,60 | 94 | 2 | 188 |
-------------------------------------
The "MAIN TABLE" doesn't need to actually have the new columns "physically" inserted. I would very much prefer if they could just be displayed in the output very much like "SELECT Points * Weight AS Sum" would produce where "Sum" would be displayed but not actually inserted in the table. BUT OK, if it needs to actually be inserted then I will go with that.
How can this be done?
You are looking for a simpler INNER JOIN statement. Please notice that Sum is wrapped as it is a Reserved word in most SQL variants. Please try to avoid naming items with these words.
SELECT m.DoubleValue
, s.Points
, s.Weight
, [Sum] = s.Points * s.Weight
FROM MainTable AS m
INNER JOIN SecondTable AS s ON m.DoubleValue = s.DoubleValue
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
I have a DB table which has some data as follows:
LINE | QTY | USERID | DATE
-----------------------------------------
1 | 5 | qb1 | 2015-03-02 11:23:25
2 | 1 | qb2 | 2015-03-02 18:24:03
3 | 3 | ch1 | 2015-03-03 05:38:49
1 | 2 | qb1 | 2015-03-03 08:47:02
2 | 4 | qb2 | 2015-03-03 14:01:31
3 | 2 | ch1 | 2015-03-03 21:11:53
1 | 4 | qb1 | 2015-03-04 09:34:04
2 | 5 | qb2 | 2015-03-04 15:29:27
3 | 1 | ch1 | 2015-03-04 19:28:33
As you can see I have only 3 unique LINE values in the DB. I require a LINQ query to select the latest record of every line. The date can be any date, I just need the latest status of the lines based on "DATE" field.
At the moment I am doing it very roughly something like this:
var line1 = db.GetTable<lnk_sts>().Where(x=> x.LINE== 1).OrderByDescending(x => x.DATE).FirstOrDefault();
Same for the other 2. What I Require is a list of lnk_sts with only the ones with a bigger date, in this case:
LINE | QTY | USERID | DATE
---------------------------------------
1 | 4 | qb1 | 2015-03-04 09:34:04
2 | 5 | qb2 | 2015-03-04 15:29:27
3 | 1 | ch1 | 2015-03-04 19:28:33
What you need to do is, group on Line and then take the first item in group after ordering in descending.
db.GetTable<lnk_sts>()
.GroupBy(x=>x.LINE)
.Select(x=>x.OrderByDescending(o=>o.DATE).FirstOrDefault())
.ToList();
First group by the line, then order by date and take the last item.
var result = db.GetTable<lnk_sts>().GroupBy(x=> x.LINE).Select(x => x.OrderBy(y => y.Date).Last())
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))};
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.