I'm trying to retrieve DBName, DBNo, DBAmount, DBCountedAmount from Table A and include NewFormNo from Table B so I did this
Table A
|DBName |DBNo | DBAmount | DBCountedAmount |
|-------|--------|----------|---------------------|
|Derek |503456 | 2000 | 2000 |
|John |554422 | 40000 | 4000 |
Table B
|DBName |DBNo | DBAmount | DBCountedAmount | FormNo|
|-------|--------|----------|---------------------|-------|
|Derek |503456 | 2000 | 2000 |00001 |
|John |554422 | 40000 | 4000 |00002 |
So I did this , but it doesnt return the row I want
SELECT A.DBName,A.DBNo,A.DBAmount,A.DBCountedAmount,B.FormNo FROM Table A LEFT JOIN Table B ON A.DBNo=B.DBNo AND A.DBNo= '503456'
I want to retrieve this
|DBName |DBNo | DBAmount | DBCountedAmount | FormNo|
|-------|--------|----------|---------------------|-------|
|Derek |503456 | 2000 | 2000 |00001 |
Change this
AND A.DBNo= '503456'
to this
WHERE A.DBNo= '503456'
Also, what is the type of DBNo? If it's numeric, you can remove the ''
try this :
SELECT A.DBName, A.DBNo, A.DBAmount, A.DBCountedAmount
FROM Table A
LEFT JOIN Table B ON A.DBNo=B.DBNo
WHERE A.DBNo= '503456'
As per your question there is no need of left outer join. You can directly get by using inner join like this:
SELECT distinct a.DBname, a.DBno, a.Dbamount, a.Dbamountcount, b.FormNo
FROM tableA a inner join tableB b
on a.DBno = b.DBno
and a.DBno = 503456
Related
I am unable to figure out how to join a couple of tables together when multiple columns in one table refer to another table.
For example, I have a "document_statuses" table:
document_statuses table:
+-----------+-------------+
| status_id | status_name |
+-----------+-------------+
| 1 | RECEIVED |
| 2 | MISSING |
| 3 | NOT_NEEDED |
+-----------+-------------+
Now in another table, I am tracking the status of multiple documents:
filings table:
+-----------+-------------+----------------+----------------+----------------+
| filing_id | filing_name | doc1_status_id | doc2_status_id | doc3_status_id |
+-----------+-------------+----------------+----------------+----------------+
| 1 | John | 1 | 3 | 2 |
| 2 | Mikaela | 2 | 3 | 2 |
| 3 | Sam | 1 | 2 | 1 |
+-----------+-------------+----------------+----------------+----------------+
How would I write a query that pulls the status_name in for each column and produce the following result:
+-------------+-------------+-------------+------------+
| Filing Name | Doc1 Status | Doc2 Status | Doc3Status |
+-------------+-------------+-------------+------------+
| John | RECEIVED | NOT_NEEDED | MISSING |
| Mikaela | MISSING | NOT_NEEDED | MISSING |
| Sam | RECEIVED | MISSING | RECEIVED |
+-------------+-------------+-------------+------------+
I'm aware of how to do this when looking up a single field from document_statuses per row, but not multiple. If I only had one column in documents that referred to document_statuses, I'd do a simple JOIN:
SELECT filing_name, status_name
FROM documents d
LEFT JOIN document_statuses ds ON d.doc1_status = ds.status_id
But how do I do that when I need more than one?
You will need to join the statuses table multiple times and then alias the columns in the select clause to be formatted to be what you want. Please note that you have to alias the tables in the join clause so that you can reference the columns in the select clause of the statement.
SELECT filing_name
, ds1.status_name AS 'Doc1 Status'
, ds2.status_name AS 'Doc2 Status'
, ds3.status_name AS 'Doc3 Status'
FROM documents d
LEFT JOIN document_statuses ds1 ON d.doc1_status = ds1.status_id
LEFT JOIN document_statuses ds2 ON d.doc2_status = ds2.status_id
LEFT JOIN document_statuses ds3 ON d.doc3_status = ds3.status_id
You'll need to do three times joins with same table using different aliases for table.
SELECT filing_name, ds.status_name, ds1.status_name,
ds2.status_name FROM documents d
LEFT JOIN document_statuses ds ON d.doc1_status
LEFT JOIN document_statuses ds1 ON d.doc1_status
LEFT JOIN document_statuses ds2 ON d.doc1_status
You can do this:
select t1.filing_name, t2.status_name as doc1_status, t3.status_name as doc2_status, t4.status_name as doc3_status
from filings_table t1
inner join statuses_table t2 on t1.doc1_status_id = t2.status_id
inner join statuses_table t3 on t1.doc2_status_id = t3.status_id
inner join statuses_table t4 on t1.doc3_status_id = t4.status_id
I'm trying to join more than 2 tables using 1 same key reference,
it works fine when I join two 2 tables using left join like this :
SELECT userProfile.UserProfileID, userProfile.name, jobPosition.levelname
FROM master.eliUserProfile userProfile
LEFT JOIN master.eliJobPosition jobPosition ON userProfile.UserProfileId = jobPosition.UserProfileID
where userProfile.UserProfileId = '5001'
Result :
userProfileid | name | levelName |
-----------------+---------+--------------+
5001 | dirdple | Direktur PLE |
5001 | dirdple | Direktur PLE |
But when I want to join another table into it, it return double values, I am using the master table reference (which is UserProfile) :
SELECT userProfile.UserProfileID, userProfile.name, jobPosition.levelname, userAcmMapping.UserAcmMappingId, userAcmMapping.RefID
FROM master.eliUserProfile userProfile
LEFT JOIN master.eliJobPosition jobPosition
ON userProfile.UserProfileId = jobPosition.UserProfileID
LEFT JOIN transactions.eliUserAcmMapping userAcmMapping
ON userProfile.UserProfileId = userAcmMapping.UserProfileID
where userProfile.UserProfileId = '5001'
and it turned out to resulted like this :
userProfileId | name | levelName | UserAcmMappingId | refId |
-----------------+---------+--------------+------------------+-------+
5001 | dirdple | Direktur PLE | 1 | 21 |
5001 | dirdple | Direktur PLE | 7 | 22 |
5001 | dirdple | Direktur PLE | 158 | 23 |
5001 | dirdple | Direktur PLE | 1 | 21 |
5001 | dirdple | Direktur PLE | 7 | 22 |
5001 | dirdple | Direktur PLE | 158 | 23 |
Is it because Iam using the same key(userProfile.UserProfileId)? Fyi, the 3rd table (userAcmMapping) have 3 values with UserProfileId=5001 and 2nd table (jobPosition) have 2 values with UserProfileId=5001.
And the table I want to be referenced is the second table with 2 values (userProfileId=5001)..
Thank you for any help..
It is because you are joining two different tables to one table with the same key. You are joining jobPositions and userAcmMapping to userProfile. I mean there are two joins on one table with the same field, so the result is doubled.
You should instead join jobPositions to userProfile and join userAcmMapping to jobPositions, like this:
SELECT userProfile.UserProfileID, userProfile.name, jobPosition.levelname, userAcmMapping.UserAcmMappingId, userAcmMapping.RefID
FROM master.eliUserProfile userProfile
LEFT JOIN master.eliJobPosition jobPosition
ON userProfile.UserProfileId = jobPosition.UserProfileID
LEFT JOIN transactions.eliUserAcmMapping userAcmMapping
ON jobPosition.UserProfileID = userAcmMapping.UserProfileID
where userProfile.UserProfileId = '5001'
Here it is one join per table.
Note: I didn't test the code, since I don't have actual tables, but it should work.
I am trying to figure out the best way to use a JOIN in MSSQL in order to do the following:
I have two tables. One table contains technician IDs and an example of one data set would be as follows:
+--------+---------+---------+---------+---------+
| tagid | techBid | techPid | techFid | techMid |
+--------+---------+---------+---------+---------+
| 1-1001 | 12 | 0 | 11 | 6 |
+--------+---------+---------+---------+---------+
I have another table that stores the names of these technicians:
+------+-----------+
| TTID | SHORTNAME |
+------+-----------+
| 11 | Steven |
| 12 | Mark |
| 6 | Pierce |
+------+-----------+
If the ID of a technician in the first table is 0, there is no technician of that type for that row (types are either B, P, F, or M).
I am trying to come up with a query that will give me a result that contains all of the data from table 1 along with the shortnames from table 2 IF there is a matching ID, so the result would look something like the following:
+--------+---------+---------+---------+---------+----------------+----------------+----------------+----------------+
| tagid | techBid | techPid | techFid | techMid | techBShortName | techPShortName | techFShortName | techMShortName |
+--------+---------+---------+---------+---------+----------------+----------------+----------------+----------------+
| 1-1001 | 12 | 0 | 11 | 6 | Mark | NULL | Steven | Pierce |
+--------+---------+---------+---------+---------+----------------+----------------+----------------+----------------+
I am trying to use a JOIN to do this, but I cannot figure out how to join on multiple columns multiple times to where it would look something like
Select table1.tagid, table1.techBid, table1.techPid, table1.techFid, table1.techMid, table2.shortname
FROM table1
INNER JOIN table2 on //Dont know what to put here
You need to use left joins like this:
Select table1.tagid, table1.techBid, table1.techPid, table1.techFid, table1.techMid,
t2b.shortname, t2p.shortname, t2f.shortname, t2m.shortname,
FROM table1
LEFT JOIN table2 t2b on table1.techBid = t2b.ttid
LEFT JOIN table2 t2p on table1.techPid = t2p.ttid
LEFT JOIN table2 t2f on table1.techFid = t2f.ttid
LEFT JOIN table2 t2m on table1.techMid = t2m.ttid
you just do mutiple left join
select tech.techPid, techPname.SHORTNAME
, tech.techFid, techFname.SHORTNAME
from tech
left join techName as techPname
on tech.techPid = techPname.TTID
left join techName as techFname
on tech.techFid = techFname.TTID
http://sqlfiddle.com/#!4/24637/1
I have three tables, (better details/data shown in sqlfiddle link), one replacing another, and a cross reference table in between. One of the fields in each of the table uses the cross reference (version), and another one of the fields in each of the tables is the same (changeID).
I need a query that when passed a list of new_version + new_changeType, along with the equivalent original_version + old_changeType (if there is an old version equivalent) PLUS any old changeIDs that were 'missed' in the conversion of data.
TABLES (fields on the same line are equivalent)
OLD_table | XREF_table | NEW_Table
original_version | original_version |
changeID | | changeID
OLD_changeType | |
| new_version | new_version
| | NEW_changeType
DATA
111,1,CT1 | 111,AAA | AAA,1,ONE
111,2,CT2 | 222,BBB | AAA,2,TWO
222,1,CT1 | 333,DDD | BBB,1,ONE
222,2,CT2 | | BBB,2,TWO
222,3,CT3 | | CCC,1,ONE
333,1,CT1 | |
444,1,CT1 | |
If passed the following list, the result set should look like so. (order doesnt matter)
AAA,BBB,CCC
| NEW_VERSION | NEW_CHANGE_TYPE| ORIGINAL_VERSION | CHANGEID | OLD_CHANGE_TYPE |
|-------------|----------------|------------------|----------|-----------------|
| AAA | ONE | 111 | 1 | CT1 |
| AAA | TWO | 111 | 2 | CT2 |
| BBB | ONE | 222 | 1 | CT1 |
| BBB | TWO | 222 | 2 | CT2 |
| CCC | ONE | (null) | (null) | (null) |
| (null) | (null) | 222 | 3 | CT3 |
I'm having trouble getting ALL the data required. I've played with the following query, however I seem to either 1) miss a row or 2) get additional rows not matching the requirements.
The following queries I've played with are as follows.
select
a.new_version,
a.Change_type,
c.original_version,
c.changeID,
c.OLD_Change_type
from NEW_TABLE a
LEFT OUTER JOIN XREF_TABLE b on a.new_version = b.new_version
FULL OUTER JOIN OLD_TABLE c on
b.original_version = c.original_version and a.changeID = c.changeID
where (b.new_version in ('AAA','BBB','CCC') or b.new_version is null);
select
a.new_version,
a.Change_type,
c.original_version,
c.changeID,
c.OLD_Change_type
from NEW_TABLE a
FULL JOIN XREF_TABLE b on a.new_version = b.new_version
FULL JOIN OLD_TABLE c on
b.original_version = c.original_version and a.changeID = c.changeID
where (a.new_version in ('AAA','BBB','CCC'));
The first returns one 'extra' row with the 333,DDD data, which is not specified from the input.
The seconds returns one less row (with the changeID from the old table "missed" from when this data was converted over.
Any thoughts or suggestions on how to solve this?
First inner join old_table and xref_table, as you are not interested in any old_table entries without an xref_table entry. Then full outer join new_table. In your WHERE clause be aware that new_table.new_version can be null, so use coalesce to use xref_table.new_version in this case to limit your results to AAA, BBB and CCC. That's all.
select
coalesce(n.new_version, x.new_version) as new_version,
n.change_type,
o.original_version,
o.changeid,
o.old_change_type
from old_table o
inner join xref_table x
on x.original_version = o.original_version
full outer join new_table n
on n.new_version = x.new_version
and n.changeid = o.changeid
where coalesce(n.new_version, x.new_version) in ('AAA','BBB','CCC')
order by 1,2,3,4,5
;
Here is your fiddle: http://sqlfiddle.com/#!4/24637/11.
BTW: Better never use random aliases like a, b and c that don't indicate what table is meant. That makes the query harder to understand. Use the table's first letter(s) or an acronym instead.
Is it possible to join these tables:
Log table:
+--------+---------------+------------+
| name | ip | created |
+--------+---------------+------------+
| 408901 | 178.22.51.168 | 1390887682 |
| 408901 | 178.22.51.168 | 1390927059 |
| 408901 | 178.22.51.168 | 1390957854 |
+--------+---------------+------------+
Orders table:
+---------+------------+
| id | created |
+---------+------------+
| 8563863 | 1390887692 |
| 8563865 | 1390897682 |
| 8563859 | 1390917059 |
| 8563860 | 1390937059 |
| 8563879 | 1390947854 |
+---------+------------+
Result table would be:
+---------+--------------+---------+---------------+------------+
|orders.id|orders.created|logs.name| logs.ip |logs.created|
+---------+--------------+---------+---------------+------------+
| 8563863 | 1390887692 | 408901 | 178.22.51.168 | 1390887682 |
| 8563865 | 1390897682 | 408901 | 178.22.51.168 | 1390887682 |
| 8563859 | 1390917059 | 408901 | 178.22.51.168 | 1390887682 |
| 8563860 | 1390937059 | 408901 | 178.22.51.168 | 1390927059 |
| 8563879 | 1390947854 | 408901 | 178.22.51.168 | 1390927059 |
+---------+--------------+---------+---------------+------------+
Is it possible?
Espessialy, if first table is result of some query.
UPDATE
Sorry for this mistake. I want found in log who make order. So orders table relate to logs table by created field, i.e.
first row with condition (orders.created >= log.created)
This will result in a non-equi join with a horrible performance:
SELECT *
FROM t2 JOIN t1
ON t1.created =
(
SELECT MAX(t1.created)
FROM t1 WHERE t1.created <= t2.created
)
You might better go with a cursor based on a UNION like this (you probably need to add some type casts to get a working UNION):
SELECT *
FROM
(
SELECT NULL AS name, NULL AS ip, NULL AS created2, t2.*
FROM t2
UNION ALL
SELECT t1.*, NULL AS id, NULL AS created
FROM t1
) AS dt
ORDER BY COALESCE(created, created2)
Now you can process the rows in the right order and remember the rows from the last t1 row.
There is nothing to bind these 2 together.
No ID or other column exists in both tables.
If this were the case, you could join these 2 tables in a stored procedure.
At the moment you ask the first query, store the data in a newly created table, use it in the join to get your results and delete it afterwards.
Kind regards
simply you can use union
select id, created from table_2
union all
select name, ip, created from table_1