Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 months ago.
Improve this question
How can I combine results of 2 table into 3rd table?
These are 3 different tables
Table A
AC_ID
IDNT_ID
ID_DESC
123
a1000
mhyed
456
b2000
DL
769
c2000
246
2000d
BCD
357
3000f
567
600d
uhj
Table B:
b_id
b_no
b2000
7000001
d78987
909898
Table C:
c_id
c_no
2000d
678987
6789
09876
Table D: it is a table of all records from table A and common between A& B and A&C
AC_ID
IDNT_ID
No
ID_DESC
123
a1000
mhyed
456
b2000
7000001
DL
769
c3000
246
2000d
678987
BCD
357
3000f
567
600d
uhj
What would be SQL to get the result of table D ?
Table E: is the combination of Table B& C
header 1
header 2
b2000
700001
d78987
909898
2000d
678987
6789
09876
What would be SQL to get the result of table D ? also what would be SQL table E?
I tried using union and joins but was not able to get desired result
With your sample data for tbl_a, tbl_b and tbl_c use Left Joins for tbl_b and tbl_c to get the result shown as "Table D":
-- Table D SQL
Select
a.AC_ID "AC_ID",
a.IDNT_ID "IDNT_ID",
COALESCE(b.B_NO, c.C_NO) "B_C_NO",
a.ID_DESC "ID_DESC"
From
tbl_a a
Left Join
tbl_b b ON(b.B_ID = a.IDNT_ID)
Left Join
tbl_c c ON(c.C_ID = a.IDNT_ID)
Order By
a.AC_ID
/* R e s u l t :
| AC_ID |IDNT_ID |B_C_NO |ID_DESC|
|---------- |------- |------- |-------|
| 123 |a1000 | |mhyed |
| 246 |2000d |678987 |BCD |
| 357 |3000f | | |
| 456 |b2000 |7000001 |DL |
| 567 |600d | |uhj |
| 769 |c2000 | | |
*/
... and for "Table E" you just need to union tables tbl_b and tbl_c:
-- Table E SQL
Select B_ID "HEADER_1", B_NO "HEADER_2" From tbl_b Union All
Select C_ID "HEADER_1", C_NO "HEADER_2" From tbl_c
/* R e s u l t :
HEADER_1 HEADER_2
-------- --------
b2000 7000001
d78987 909898
2000d 678987
6789 09876
*/
Regards...
Related
I have two tables, one is my Main table and one is Mapping table. The simplified tables look like this :
Main :
VALUE | CUSTNAME
123 | ADELE
323 | GORTH
242 | GORTH
345 | VIX
...
Mapping :
ISSUER | CATEGORY
ADELE | A
GORTH | B
DENN | B
VIX | C
...
What I want to do is add a CATEGORY column to my Main table, so I to use a left join, but somehow it returns more rows than I originally have. And I can't check it one by one because it has around 30000 records. The increase it self is miniscule, 40 records, but it still a difference and it shows.
Things to note and things I already tried :
Main table can hold the same CUSTNAME while Mapping table is distinct, making it many-to-one relation.
Mapping table holds duplicate records, so I tried to select distinct it first before joining it
I already checked the NULL to see if the Mapping table miss anything, but it doesn't seems to be the case
I use both inner join and left join but it return the same result
So what did I do wrong here and how can I fix it?
My query :
SELECT A.*, B.CATEGORY AS CATEGORY
FROM Main A
LEFT JOIN
(SELECT DISTINCT * FROM Mapping) B ON A.CUSTNAME = B.Issuer
My output right now :
VALUE | CUSTNAME | CATEGORY
123 | ADELE | A
323 | GORTH | B
242 | GORTH | B
345 | VIX | C
... with extra 40 records
My expected output :
VALUE | CUSTNAME | CATEGORY
123 | ADELE | A
323 | GORTH | B
242 | GORTH | B
345 | VIX | C
... without extra 40 records
You can do it as follows if you are looking to eliminate duplicates Mapping.Issuer ONLY.
SELECT A.*, B.CATEGORY AS CATEGORY
FROM Main A
LEFT JOIN
(SELECT Issuer, MAX(CATEGORY) AS CATEGORY FROM Mapping group by Issuer) B ON A.CUSTNAME = B.Issuer
Probably you have data on Mapping table like :
insert into Mapping values
('ADELE','A'),
('GORTH','B'),
('DENN','B'),
('VIX','C'),
('VIX','D');
That means ('VIX','C'), ('VIX','D') are not duplicates
demo here
This:
SELECT DISTINCT * FROM Mapping
won't prevent duplicates. Distinct * means that the tuple(combination) of ALL columns will be considered as unique; However, if there are two rows with same Issuer but a different value in any of the other columns, it will still return multiple rows. Like this:
Issuer | ManufactureId
5623 894
5623 895
This, in turn, will make one row from A turn into multiple from the left join.
I would like to show all classes and grades of only those students who have at least one "F" grade.
Here is the source table:
ID | Students | Class | Grade
1 | Addams, W | History | A
2 | Addams, W | Biology | A
3 | Addams, W | French | B
4 | Jetson, E | Spanish | B
5 | Jetson, E | Geometry | B
6 | Jetson, E | Biology | F
7 | Rubble, B | English | F
8 | Rubble, B | Geometry | B
9 | Rubble, B | Biology | B
10 | Flintstone, P | Music | A
11 | Flintstone, P | Spanish | B
Here is a report, grouped by Students:
Addams, W
---------------French B
---------------Biology A
---------------History A
Flintstone, P
---------------Spanish B
---------------Music A
Jetson, E
---------------Biology F
---------------Geometry B
---------------Spanish B
Rubble, B
---------------Biology B
---------------Geometry B
---------------English F
Again, I would like to show all classes and grades of only those students who have at least one "F" grade, as seen below:
Jetson, E
---------------Biology F
---------------Geometry B
---------------Spanish B
Rubble, B
---------------Biology B
---------------Geometry B
---------------English F
Any assistance would be much appreciated.
Create a query with your table as the source. Drop in the Students field in the first column and put the following formula in the second column: IIf([Grade]=”F”,1,0), then save the query. (by default Access will name this column “Expr1”, but you change it to whatever you like)
Create a 2nd query using query 1 as the source, drop in the 2 columns from query 1, group on, sum the column with the formula, and in this column add a criteria of >=1, and save. You now have a table with only the students who have at least 1 “F”. (you group on by placing cursor in the grid section of the query at the bottom, right-clicking and selecting "Totals" from the prompt box)
Create a 3rd query tying the 2nd query to your original source table by connecting the Students field with a 1 to 1 match (i.e. join type 1).
You can query your table using a subquery to query on the same table for any instances having a F grade:
SELECT a.ID, a.Students, a.Class, a.Grade
FROM yourtable AS a
WHERE EXISTS
(
SELECT '1'
FROM yourtable AS b
WHERE a.Students = b.Students
AND b.Grade = 'F'
);
Next, base your report on above query.
OP here: Both answers worked; thanks again. Here is the code for the second answer:
Query 1
SELECT Students2.Students, IIf([Grade]="F",1,0) AS F_grade
FROM Students2;
Query 2
SELECT Query1.Students, Sum(Query1.F_grade) AS SumOfF_grade
FROM Query1
GROUP BY Query1.Students
HAVING (((Sum(Query1.F_grade))>=1));
Query 3
SELECT Students2.Students, Students2.Class, Students2.Grade
FROM Students2 INNER JOIN Query2 ON Students2.Students = Query2.Students;
This question already has an answer here:
Complex Postgres query
(1 answer)
Closed 7 years ago.
The db schema along with sample data is something like this -
(Country table)
| Country | Country Code |
--------------------------
ABC A
BCD B
(TransactionTable)
| SrcCountryCode | DestCountryCode| SrcCurrency| DestCurrency | SrcAmount | DestAmount |
----------------------------------------------------------------------------------------
A B X Y 200 1000
A B X Y 300 1500
B A Y X 1000 200
I want the result set to be like this -
| Corridor | Total Src Amount| Total Dest Amount | Src Currency |
-----------------------------------------------------------------
ABC-BCD 500 200 X
BCD-ABC 1000 2500 Y
I am lost on how to map the Country combinations as well as map the total amounts for destination and source subsequently in one table.
Help would be appreciated.
This sql query like this
select
d.Country+'-'+e.Country as Corridor,
TotalSrcAmount,
TotalDestAmount,
SrcCurrency
from TransactionTable a
join
(
select SrcCurrency ,sum(SrcAmount) 'TotalSrcAmount'
from TransactionTable
Group by SrcCurrency
)b on a.SrcCurrency =b.SrcCurrency
join
(
select DestCurrency,sum(DestAmount) 'TotalDestAmount'
from TransactionTable
Group by DestCurrency
)c on a.SrcCurrency =c.DestCurrency
join Countrytable d on d.Country_Code=a.SrcCountryCode
join Countrytable e on e.Country_Code=a.DestCountryCode
group by
d.country,
e.country,
a.SrcCurrency
I have a table Farm with these columns
FarmID:(primary)
Kenizy:
BarBedo:
BarBodo:
MorKodo:
These columns are palm types in some language. each column of those contains a number indicates the number of this type of palm inside a farm.
Example:
FarmID | Kenizy | BarBedo | BarBodo | MorKodo
-----------------------------------------------
3 | 20 | 12 | 45 | 60
22 | 21 | 9 | 41 | 3
I want to insert that table into the following tables:
Table Palm_Farm
FarmID:(primary)
PalmID;(primary)
PalmTypeName:
Count:
That table connects each farm with each palm type.
Example:
FarmID | PalmID | PalmTypeName | Count
-----------------------------------------------
3 | 1 | Kenizy | 20
3 | 2 | BarBedo | 12
3 | 3 | BarBodo | 45
3 | 4 | MorKodo | 60
22 | 1 | Kenizy | 21
22 | 2 | BarBedo | 9
22 | 3 | BarBodo | 41
22 | 4 | MorKodo | 3
I have to use the following table Palms in order to take the PalmID column.
PalmID:(primary)
PlamTypeName:
...other not important columns
This table is to save information about each palm type.
Example:
PalmID | PlamTypeName
-------------------------
1 | Kenizy
2 | BarBedo
3 | BarBodo
4 | MorKodo
The PalmTypeName column has the value the same as the COLUMN NAMES in the Farm table.
So my question is:
How to insert the data from Farm table to Palm_Farm considering that the PalmID exist in the Palm table
I hope I could make my question clear, I tried to solve my problem myself but the fact that the column name in the Farm table must be the column value in the Palm_Farm table couldn't know how to do it.
I can't change the table structure because we are trying to help a customer with this already existing tables
I am using SQL Server 2008 so Merge is welcomed.
Update
After the genius answer by #GarethD, I got this exception
You can use UNPIVOT to turn the columns into rows:
INSERT Palm_Farm (FarmID, PalmID, PalmTypeName, [Count])
SELECT upvt.FarmID,
p.PalmID,
p.PalmTypeName,
upvt.[Count]
FROM Farm AS f
UNPIVOT
( [Count]
FOR PalmTypeName IN ([Kenizy], [BarBedo], [BarBodo], [MorKodo])
) AS upvt
INNER JOIN Palms AS p
ON p.PalmTypeName = upvt.PalmTypeName;
Example on SQL Fiddle
The docs for UNPIVOT state:
UNPIVOT performs almost the reverse operation of PIVOT, by rotating columns into rows. Suppose the table produced in the previous example is stored in the database as pvt, and you want to rotate the column identifiers Emp1, Emp2, Emp3, Emp4, and Emp5 into row values that correspond to a particular vendor. This means that you must identify two additional columns. The column that will contain the column values that you are rotating (Emp1, Emp2,...) will be called Employee, and the column that will hold the values that currently reside under the columns being rotated will be called Orders. These columns correspond to the pivot_column and value_column, respectively, in the Transact-SQL definition.
To explain further how unpivot works, I will look at the first row original table:
FarmID | Kenizy | BarBedo | BarBodo | MorKodo
-----------------------------------------------
3 | 20 | 12 | 45 | 60
So what UPIVOT will do is look for columns specified in the UNPIVOT statement, and create a row for each column:
SELECT upvt.FarmID, upvt.PalmTypeName, upvt.[Count]
FROM Farm AS f
UNPIVOT
( [Count]
FOR PalmTypeName IN ([Kenizy], [BarBedo])
) AS upvt;
So here you are saying, for every row find the columns [Kenizy] and [BarBedo] and create a row for each, then for each of these rows create a new column called PalmTypeName that will contain the column name used, then put the value of that column into a new column called [Count]. Giving a result of:
FarmID | Kenizy | Count |
---------------------------
3 | Kenizy | 20 |
3 | BarBedo | 12 |
If you are running SQL Server 2000, or a later version with a lower compatibility level, then you may need to use a different query:
INSERT Palm_Farm (FarmID, PalmID, PalmTypeName, [Count])
SELECT f.FarmID,
p.PalmID,
p.PalmTypeName,
[Count] = CASE upvt.PalmTypeName
WHEN 'Kenizy' THEN f.Kenizy
WHEN 'BarBedo' THEN f.BarBedo
WHEN 'BarBodo' THEN f.BarBodo
WHEN 'MorKodo' THEN f.MorKodo
END
FROM Farm AS f
CROSS JOIN
( SELECT PalmTypeName = 'Kenizy' UNION ALL
SELECT PalmTypeName = 'BarBedo' UNION ALL
SELECT PalmTypeName = 'BarBodo' UNION ALL
SELECT PalmTypeName = 'MorKodo'
) AS upvt
INNER JOIN Palms AS p
ON p.PalmTypeName = upvt.PalmTypeName;
This is similar, but you have to create the additional rows yourself using UNION ALL inside the subquery upvt, then choose the value for [Count] using a case expression.
To update when the row exists you can use MERGE
WITH Data AS
( SELECT upvt.FarmID,
p.PalmID,
p.PalmTypeName,
upvt.[Count]
FROM Farm AS f
UNPIVOT
( [Count]
FOR PalmTypeName IN ([Kenizy], [BarBedo], [BarBodo], [MorKodo])
) AS upvt
INNER JOIN Palms AS p
ON p.PalmTypeName = upvt.PalmTypeName
)
MERGE Palm_Farm WITH (HOLDLOCK) AS pf
USING Data AS d
ON d.FarmID = pf.FarmID
AND d.PalmID = pf.PalmID
WHEN NOT MATCHED BY TARGET THEN
INSERT (FarmID, PalmID, PalmTypeName, [Count])
VALUES (d.FarmID, d.PalmID, d.PalmTypeName, d.[Count])
WHEN MATCHED THEN
UPDATE
SET [Count] = d.[Count],
PalmTypeName = d.PalmTypeName;
I'm trying to use a join on three tables query I found in another post (post #5 here). When I try to use this in the SQL tab of one of my tables in phpMyAdmin, it gives me an error:
#1066 - Not unique table/alias: 'm'
The exact query I'm trying to use is:
select r.*,m.SkuAbbr, v.VoucherNbr from arrc_RedeemActivity r, arrc_Merchant m, arrc_Voucher v
LEFT OUTER JOIN arrc_Merchant m ON (r.MerchantID = m.MerchantID)
LEFT OUTER JOIN arrc_Voucher v ON (r.VoucherID = v.VoucherID)
I'm not entirely certain it will do what I need it to do or that I'm using the right kind of join (my grasp of SQL is pretty limited at this point), but I was hoping to at least see what it produced.
(What I'm trying to do, if anyone cares to assist, is get all columns from arrc_RedeemActivity, plus SkuAbbr from arrc_Merchant where the merchant IDs match in those two tables, plus VoucherNbr from arrc_Voucher where VoucherIDs match in those two tables.)
Edited to add table samples
Table arrc_RedeemActivity
RedeemID | VoucherID | MerchantID | RedeemAmt
----------------------------------------------
1 | 2 | 3 | 25
2 | 6 | 5 | 50
Table arrc_Merchant
MerchantID | SkuAbbr
---------------------
3 | abc
5 | def
Table arrc_Voucher
VoucherID | VoucherNbr
-----------------------
2 | 12345
6 | 23456
So ideally, what I'd like to get back would be:
RedeemID | VoucherID | MerchantID | RedeemAmt | SkuAbbr | VoucherNbr
-----------------------------------------------------------------------
1 | 2 | 3 | 25 | abc | 12345
2 | 2 | 5 | 50 | def | 23456
The problem was you had duplicate table references - which would work, except for that this included table aliasing.
If you want to only see rows where there are supporting records in both tables, use:
SELECT r.*,
m.SkuAbbr,
v.VoucherNbr
FROM arrc_RedeemActivity r
JOIN arrc_Merchant m ON m.merchantid = r.merchantid
JOIN arrc_Voucher v ON v.voucherid = r.voucherid
This will show NULL for the m and v references that don't have a match based on the JOIN criteria:
SELECT r.*,
m.SkuAbbr,
v.VoucherNbr
FROM arrc_RedeemActivity r
LEFT JOIN arrc_Merchant m ON m.merchantid = r.merchantid
LEFT JOIN arrc_Voucher v ON v.voucherid = r.voucherid