I have two temp tables.
Table 1 contains all the string info
ID | string1 | string2 | etc...
Table 2 contains of the int values
ID | int1 | int2 | etc...
They both share a unique ID.
I need to join them so that it first shows all the the info from table 1 and WHEN there is a matching ID in table 2 to add those values to the end of the table, otherwise when table 2 does not contain that ID to put in a 0, There is never a case when table 1 does not have the ID that is in Table 2
So when the ID is in table 2
ID | String1 | String2 | int1 | int2 |
AND when the ID is not in Table 2
ID | String1 | String2 | 0 | 0 |
When you need all rows from left table use LEFT JOIN and for controlling value of table2 use ISNULL function.
Select t1.ID, t1.string1, t1.string2, ISNULL(t2.int1, 0) int1, ISNULL(t2.int2, 0) int2
FROM [table 1] t1
LEFT JOIN [table 2] t2 ON t1.ID = t2.ID
Also it is not called merging tables, but joining.
Related
update column values from another table with different column name but same column value
I have two tables as mentioned below :
Table1
ID | Name
1 | A
2 | A
3 | A
4 | A
Table2
IDX | Name
1 | XYZ
2 | PQR
3 | PPS
update Table1
set Name = (Select Name from Table2 where Table1.ID = Table2.IDX)
I'm getting below result after executing above query.
ID | Name
1 | XYZ
2 | PQR
3 | PPS
4 | NULL
But I need result as mentioned below:
ID | Name
1 | XYZ
2 | PQR
3 | PPS
4 | A
Can somebody help with this ? Thanks!
Using an update join we can try:
UPDATE t1
SET Name = t2.Name
FROM Table1 t1
INNER JOIN Table2 t2
ON t2.IDX = t1.ID;
Only records from Table1 which match to something in Table2 will be updated. This avoids the problem of making a null assignment from which your current approach suffers. You could make the following slight change to your current update to avoid the problem:
UPDATE Table1
SET Name = (SELECT COALESCE(t2.Name, Table1.Name) FROM Table2 t2
WHERE Table1.ID = t2.IDX);
I have two tables in SQL Server, Say in table1 I have two columns Key1Display and Key2Display, they are of datatype bit and used to control whether to display the values in table2, and table 2 will have 2 columns Key1 and Key2.
What I am trying to achieve is a sort of cross join, say if table 1 has 3 rows:
| Key1Display | Key2Display |
+---------------------+------------------+
| 0 | 1 |
| 1 | 0 |
| 1 | 1 |
Say in table 2 there are 2 rows
| Key1 | Key2 |
+---------------------+------------------+
| Row1Key1value | Row1Key2value |
| Row2Key1value | Row2Key2value |
Then based on these two tables, I want to have a query to display 6 (2*3) rows and 1 column of results like this:
null:Row1Key2value
Row1Key1Value:null
Row1Key1Value:Row1Key2value
null:Row2Key2value
Row1Key2Value:null
Row1Key2Value:Row2Key2value
So something like:
select
case when t1.Key1Display = 1 then coalesce(t2.Key1,'??') else 'null' end
+ ':' + case when t1.Key2Display = 1 then coalesce(t2.Key2,'??') else 'null' end
-- And so on for as many keys as you have
from table1 t1
cross join table2 t2
I am having some difficulty in doing a LEFT OUTER JOIN in SQLite3 and have not been able to find the resolution in StackOverflow's existing documents, but that may be just a reflection of ....
Basically, the issue is that the second table does not have some matching rows and I want the result set to contain NULL values for those rows.
The Table Structures:
(a) tblITEMS with columns:
ID (integer, primary key, not null)
DESCR (Text); i.e., description
(b) tblVALUES with columns:
ID (integer, primary key, not null)
ITEM_ID (integer, not null, foreign key to tblITEMS.ID)
VAL_DT (not null); i.e., the valuation date
VALUE (real, not null, default 0)
The Data:
(a) tblITEMS has five (5) rows.
__ID__|_DESCR_|
:----:|:-----:|
1 | Item1 |
2 | Item2 |
3 | Item3 |
4 | Item4 |
5 | Item5 |
(b) tblVALUES has four (4) rows with
(bi) two rows have the same ITEM_ID, but different VAL_DTs
(bii) two rows have ITEM_IDs different from (bi).
(c) There are zero (0) rows that match two (2) of the tblITEM IDs.
__ID__|_ITEM_ID_|__VAL_DT_____|__VALUE__|
:----:|:-------:|:-----------:|:-------:|
1 | 1 | 2000-01-01 | 10 |
2 | 2 | 2000-01-01 | 20 |
3 | 2 | 2010-01-01 | 200 |
4 | 3 | 2000-01-01 | 40 |
The desired result set:
Five (5) rows, one for each tblITEMS row, which contains NULL entries for the tblVALUES columns that do not have a matching ITEM_ID; i.e. do not exist.
SQL script that gives three (3) rows, each of which has the appropriate values from the tblVALUES table.
select a.ID, a.DESCR, b.ID as VAL_ID, b.ITEM_ID, Date(b.Val_dt) as Val_dt, b.VALUE
from
tblItems a
, tblValues b
--left outer join tblValues on a.id = b.item_id
where
a.id = b.item_id
and
b.val_dt = (Select Max(b.val_dt) from tblValues b where (a.id = b.ITEM_ID))
order by a.id
Above SQL script with the "left outer join" line uncommented yeilds a result set with:
(a) Twelve (12) rows.
(b) Four (4) duplicates of each of three (3) unique rows (same as returned by 4. above). The unique rows all have appropriate values from tblVALUES.
(c) Zero (0) rows corresponding to the tblITEMS that do not have a corresponding row in the tblVALUES table.
THE QUESTION:
How should the SQL script be modified so that the result set contains five (5) rows, one for each tblITEMS row AND contains NULL values for the tblITEM rows that do not have a corresponding row in the tblVALUES table?
Expected / desired result set:
__ID__|_DESCR_|_ITEM_ID_|__VAL_DT_____|__VALUE__|
:----:|:-----:|:-------:|:-----------:|:-------:|
1 | Item1 | 1 | 2000-01-01 | 10 |
2 | Item2 | 2 | 2010-01-01 | 200 |
3 | Item3 | 3 | 2000-01-01 | 40 |
4 | Item4 | NULL | NULL | NULL |
5 | Item5 | NULL | NULL | NULL |
Note: NULLs may be zero or a "null date".
I'm answering my own question because I've solved the problem.
I am somewhat embarrassed by how simple the solution was.
In any case, my fundamental problem was that I did not fully understand that the "JOIN" clauses are actually part of the main "FROM" clause, which means that the table on the right side of the join and its alias definition should only appear in the join clause.
The actual solution is:
Select a.ID
, a.DESCR
, b.ID AS VALUES_ID
, b.ITEM_ID
, b.VAL_DT
, b.VALUE
FROM tblITEMS a
LEFT OUTER JOIN tblVALUES b ON a.ID = b.ITEM_ID
AND b.val_dt = (Select Max(b.val_dt)
From tblVALUES b
Where a.ID = b.ITEM_ID)
Order by
a.ID
Regards,
John
Let's say I have this table
(Simplified, my query have more tables involved)
ConsignmentItem
ID |Item code| Name | Quantity
1 | 00000 | A | 3
2 | 11111 | B | 2
And this other table
PickingItem
ID |ConsignmentID|Quantity
1 | 1 | 1
What my query does is to join both tables and print the amount of products ordered and the amount of products already registered. I would like to get as result the following table
Item Code| Name | Quantity_Ordered | Quantity_Registered
00000 | A | 3 | 1
11111 | B | 2 | 0
My query works whenever the item exist on "PickingItem", if it doesn't it prints the same "Quantity_Registered" as the above row, using my query I get as result the following table
Item Code| Name | Quantity_Ordered | Quantity_Registered
00000 | A | 3 | 1
11111 | B | 2 | 1(this is wrong)
This is the query i'm using
SELECT C.Barcode AS 'Item Code',C.ProductName AS 'Name', C.Quantity AS 'Quantity_Ordered', ISNULL(P.Quantity,0) AS 'Quantity_Registered'
FROM PICKING.OrderPickingItem P
JOIN PICKING.OrderPicking OP ON P.PickingID = OP.PickingID
JOIN ORDERS.ConsignmentItem C ON OP.ConsignmentID = C.ConsignmentID
WHERE P.PickingID = 1 --For testing
Anyone know what could I do to, if the product doesn't exist on OrderPickingItem, then set P.Quantity = 0 for that specific row?
EDIT:
Structure of the tables
OrderPickingItem
PickingItemID PK
PickingID FK
ConsignmentItemID FK
Quantity
--other not used columns for this query
OrderPicking
PickingID PK
ConsignmentID FK
--other not used columns for this query
ConsignmentItem
ConsignmentItemID PK
ConsignmentID FK
Barcode
Quantity
ProductName
--other not used columns for this query
You are obviously looking for an outer join:, you want to show ConsignmentItem records even when there is no matching picking.
select
C.Barcode AS "Item Code",
C.ProductName AS "Name",
C.Quantity AS "Quantity_Ordered",
ISNULL(P.Quantity, 0) AS "Quantity_Registered"
from ORDERS.ConsignmentItem c
left join PICKING.OrderPicking op on OP.ConsignmentID = C.ConsignmentID
left join PICKING.OrderPickingItem P on P.PickingID = OP.PickingID
and P.ConsignmentItemID = C.ConsignmentItemID;
Do an outer join and something like ifnull(p.id, 0) for the quantity in the select clause.
For e.g. I have below table1 and table3. The 'Counts' field in table2 should be updated based on valuess field in table1 and table3. i.e. 23 appears 4 times in table1 and table3 and 45 appears once. Table2 should be updated with that count.
table1
Id | Data | Valuess
1 | rfsd | 23
2 | fghf | 45
3 | rhhh | 23
table3
Id | Data | Valuess
1 | rfsd | 23
2 | tfgy | 23
table2
Id | Fields | Counts
1 | 23 | 4
2 | 45 | 1
I am using the below stored procedure to achieve this.
WITH t13 AS (
SELECT Id, Data, Valuess FROM Table1 UNION ALL SELECT Id, Data, Valuess FROM Table3),
cte AS (SELECT Valuess,COUNT(*) AS Count2 FROM t13 GROUP BY Valuess)
UPDATE t2
SET t2.Counts = cte.Count2
FROM Table2 t2 JOIN cte ON t2.Fields = cte.Valuess;
QUESTION
Now instead of above table data, i have below table data....
table1
Id | Data | Valuess
1 | rfsd | 004561
2 | fghf | 0045614
3 | rhhh | adcwyx
table3
Id | Data | Valuess
1 | rfsd | 0045614
2 | tfgy | 004561
table2
Id | Fields | Counts
1 | 0045614 | 4
2 | adcwyxv | 1
So here we have alphanumeric data in valuess field of table1 and table3. Also we have data like '004561' and '0045614'
I want to clip off the 7th element of the field and compare it with clipping off 7th element in the table 3. i.e. 004561, 004561 and adcwyx will be taken from table1. 004561 and 004561 will be taken from table3 and compared with 004561 and adcwyx of table2 ( we need to clip off 7th element in table2 first) and then compare.
The final result should be as shown in table2.
SUBSTRING should do it.
WITH t13 AS (
SELECT Id, Data, SUBSTRING(Valuess,1,6) AS [Values]
FROM Table1
UNION ALL
SELECT Id, Data, SUBSTRING(Valuess,1,6) AS [Values]
FROM Table3
)
, cte AS (
SELECT [Values],COUNT(*) AS Count2
FROM t13 GROUP BY [Values]
)
UPDATE t2
SET t2.Counts = cte.Count2
FROM Table2 t2 JOIN cte ON SUBSTRING(t2.Fields,1,6) = cte.[Values];