MySQL Query That Can Pull the Data I am Seeking? - sql

On the project I am working on, I am stuck with the table structure from Hades. Two things to keep in mind:
I can't change the table structure right now. I'm stuck with it for the time being.
The queries are dynamically generated and not hard coded. So, while I am asking for a query that can pull this data, what I am really working toward is an algorithm that will generate the query I need.
Hopefully, I can explain the problem without making your eyes glaze over and your brain implode.
We have an instance table that looks (simplified) along these lines:
Instances
InstanceID active
1 Y
2 Y
3 Y
4 N
5 Y
6 Y
Then, there are multiple data tables along these lines:
Table1
InstanceID field1 reference_field2
1 John 5
2 Sally NULL
3 Fred 6
4 Joe NULL
Table2
InstanceID field3
5 1
6 1
Table3
InstanceID fieldID field4
5 1 Howard
5 2 James
6 2 Betty
Please note that reference_field2 in Table1 contains a reference to another instance.
Field3 in Table2 is a bit more complicated. It contains a fieldID for Table 3.
What I need is a query that will get me a list as follows:
InstanceID field1 field4
1 John Howard
2 Sally
3 Fred
The problem is, in the query I currently have, I do not get Fred because there is no entry in Table3 for fieldID 1 and InstanceID 6. So, the very best list I have been able to get thus far is
InstanceID field1 field4
1 John Howard
2 Sally
In essence, if there is an entry in Table1 for Field 2, and there is not an entry in Table 3 that has the instanceID contained in field2 and the field ID contained in field3, I don't get the data from field1.
I have looked at joins till I'm blue in the face, and I can't see a way to handle the case when table3 has no entry.

LEFT JOIN...
SELECT a.InstanceID, b.field1, d.field4
FROM instances AS a
JOIN Table1 AS b ON a.InstanceID = b.InstanceID
LEFT JOIN Table2 AS c ON b.reference_field2 = c.InstanceID
LEFT JOIN Table3 AS d ON (c.InstanceID = d.InstanceID AND c.field3 = d.fieldId)
WHERE a.active = 'Y'
The two left joins should handle the case where there are no other rows...

It would help if you posted the query you have, because I think you have some mistakes in the table descriptions here, so it's not very clear how are the tables connected.
Anyway, you probably have an inner join in your query (normally written as just JOIN). Replace it with a left outer join (LEFT JOIN). It will not require the right table to contain the row and return NULL instead of the actual value.

Related

Is there a way to return a partial blank row in SQL when joining tables through automation?

For my project, I have 2 tables. Initially I inner joined both tables (table 1 and 2) via an inner join. However, I wanted an outcome as seen in table 4 where the repeated value from table 1 is left blank instead.
For table 2, the number of rows will always vary. There will always only be 1 department ID attached to numerous function IDs. Is there a query then where regardless of the number of function IDs, the department ID will only appear as the first row as seen in table 4?
(I think to many, this might seem weird and frankly not clean data, but for mail merges within word, it is easier to field code when the data is presented this way to refrain sections from 'reprinting itself'.)
Current Code:
SELECT Table1.*, Table2.* FROM
INNER JOIN Table 2 ON Table1.DepartmentID = Table2.DepartmentID
Table 1:
Department ID
Department
1
XYZ
Table 2:
Department ID
Function ID
Function
1
1
ABC
1
2
DEF
Table 3 (inner joined):
Department ID
Department
FunctionID
Function
1
XYZ
1
ABC
1
XYZ
2
DEF
Table 4 (desired):
Department ID
Department
FunctionID
Function
1
XYZ
1
ABC
2
DEF

How to display data in SQL from multiple tables, but only if one column data matches another column?

I'm still learning SQL, so this may just be my ignorance or inability to express in a search what I'm looking for. I've spent roughly an hour searching for some variation of the title (both here and general searches on Google). I apologize, I apparently also don't know how to format here. I'll try to clean it up now that I've posted.
I have a database of customer data that I did not design. In the GUI, there are multiple tabs, and it seems like each tab earned it's own table. The tables are linked together with a field called RecordID. In one of the tables is the Customer Data tab. The way that it's organized is that a single customer record from table A can have multiple rows in table B. I only want data from column B in table B is "CompanyA" and if column A in table B = 1. Sample data is below.
Expected output:
CardNumber LastName FirstName CustomerID DataItem
------------------------------------------------------
32154 Clapton Eric 181212 CompanyA
Table A:
RecordID CardNumber LastName FirstName CustomerID
---------------------------------------------------------------
1 12345 Smith John 190201
2 12346 Jones Sandy 190202
3 23456 Petty Tom 190203
4 32154 Clapton Eric 181212
5 14728 Tyler Steven 180225
Table B:
RecordID DataID DataItem
--------------------------------
1 0 CompanyA
1 1 Yes
1 2 No
1 3 Revoked
1 4 NULL
1 5 CompanyB
2 0 CompanyB
2 1 Yes
2 2 No
2 3 NULL
2 4 24-54A
2 5 CompanyC
3 0 CompanyA
3 1 No
3 2 No
3 3 NULL
3 4 68-69B
3 5 NULL
4 0 CompanyA
4 1 Yes
4 2 Yes
5 0 CompanyB
5 1 No
5 2 No
5 5 CompanyA
The concept you're looking for is a JOIN. In this case specifically you need an INNER JOIN. Joins connects two tables together based on criteria you specify (such as matching values in fields) and merges the result into one table in the output.
Here's an example to suit your scenario:
SELECT
A.CardNumber,
A.LastName,
A.FirstName,
A.CustomerID,
B.DataItem
FROM
TableA A
INNER JOIN TableB B -- join tableB onto tableA
ON A.RecordID = B.RecordID -- in the ON clause you specify criteria by you match the fields
WHERE
B.columnA = 'CompanyA'
AND B.columnB = 1
Here's the relevant SQL Server Documentation
Also I'd advise you to potentially take a comprehensive introductory SQL tutorial, and/or find a book. A good one will introduce all of the basic, key concepts such as this to you in a logical way, then you're not grasping in the dark trying to google things for which you don't know the correct terminology.
select a.CardNumber, a.LastName, a.FirstName, a.CustomerID, b.dataitem
from tableA A inner join TableB b
on a.recordid = b.recordid
where b.columnA= 'CompanyA' and b.columnB = 1
Here is your solution,
select a.CardNumber, a.LastName, a.FirstName, a.CustomerID, b.DataItem from
tableA a
inner join tableB b
on (a.RecordID = b.RecordID)
where
b.DataItem='CompanyA'
b.RecordID=1;
Le me know if the result is not as expected
Your question is quite hard to understand, but let me give you an example that resembles the what i think you are asking.
SELECT a.*, b.DataItem FROM A a INNER JOIN B b
ON a.RecordID = b.RecordID AND
b.DataItem = `CompanyA`
At the database engine level, if you are using Microsoft technology, the most efficient structure is to use an indexed foreign key constraint on Table B, and a Primary Surrogate Key (PSK) column on Table A. The Primary Surrogate Key in your case is on the Parent table, Table A, and is called RecordID. The foreign key column with the FKC is on Table B, on the column named RecordID. Once you verify that there is a FKC (foreign key constraint on Table B, which pins both columns named RecordID between both tables on matched values), then address the GUI. At the GUI, between the tabs, you generally indicate you have a parent table with a unique set of Record IDs (one column named Record ID with absolutely unique values in each row and no empty rows on that column). There will also be child tables on each Tab in your GUI, and those are bound to the parent table in a "1 to Many (1:M)" fashion, where 1 parent has many children. Your commentary or question indicates that you also want to filter, where Record ID on the child in one of the related tabs equates to the integer value 1 on the Record ID. So, there needs to be a query somewhere:
SELECT [columns]
FROM [Table B]
INNER JOIN [Table A]
ON A.RecordID = B.RecordID
AND B.RecordID = 1;
Does that help?

Get the list for Super and sub types

Am Having the Tables in SQL server as Super and Sub types like below. Now if i have to get list of Furnitures then how can i get the list?
Furniture table:
Id FurnituretypeId NoofLegs
-------------------------------
1 1 4
2 2 4
FurnitureType table:
Id Name
-----------------
1 chair
2 cot
3 table
Chair Table:
Id Name CansSwing CanDetachable FurnitureId
------------------------------------------------------------
1 Chair1 Y Y 1
Cot Table:
Id Name CotType Storage StorageType FurnitureId
-------------------------------------------------------------------
1 Cot1 Auto Y Drawer 2
How can i get the entire furniture list as some of them are chair and some of them are cot. How can i join the these tables with furniture table and get the list?
Hmmm . . . union all and join?
select cc.*, f.*
from ((select Id, Name, CansSwing, CanDetachable,
NULL as CotType, NULL as Storage, NULL as StorageType, FurnitureId
from chairs
) union all
(select Id, Name, NULL as CansSwing, NULL as CanDetachable,
CotType, Storage, StorageType, FurnitureId
from cots
)
) cc join
furniture f
on cc.furnitureid = f.id;
This is a classical learning problem, that's why I'm not giving you the code to solve this but all the insights you need to do so.
You have multiple approaches possible, but I'm describing two simple ones:
1) Use the UNION statement to join two separate queries one for Chair and the other for Cot, bare in mind that both SELECT have to return the same structure.
SELECT
a1,
a2,
etc..
FROM table1 a1
JOIN table2 a2 ON a1.some = a2.some
UNION
SELECT
a1,
a3,
etc..
FROM table1 a1
JOIN table3 a3 ON a1.some = a3.some
2) You can do it all in one SELECT statement using a LEFT JOIN to both tables and and in the select using COALESCE or ISNULL to get the values for one table or the other. In the WHERE condition you have to force one or the other join to be not null.
SELECT
a1,
COALESCE(a2,a3) as col2
FROM table1
LEFT JOIN table2 a2 ON a1.some = a2.some
LEFT JOIN table3 a3 ON a1.some = a3.some
WHERE
a2.some IS NOT NULL
OR a3.some IS NOT NULL
Mapping objects into relational models takes a degree of understanding of what is possible vs. what is wise in an RDBMS. Object oriented database systems tried to go after problems like this (generally without much success) precisely because the problem statement is arguably not the right one.
Please consider just putting all of these in one table. Then use null for the fields that don't really matter for each sub-type. You will likely end up being a lot happier in the end since you can spend less time at runtime doing joins and instead just query the information you need and use indexing on the same table to find the fasted path for each query you want to run.
SELECT * FROM CombinedTable;

How to join all Oracle tables in new table

I have an oracle DB with a lot of tables (more than 60).
For Example:
Table 1
ID STRING DATA
1 ABC READ
2 CDE WRITE
3 FGH READ
4 HSS WRITE
5 FFH WRITE
Table 2
ID Name Feb
1 Deven 12
4 Monish 21
5 Ritesh 22
Table 3
ID STRING DATA READY
1 ABC READ OK
2 CDE WRITE NO
3 FGH READ OK
I need to create a new table where for each ID It shows all the fields and informations contained in all the db tables for that ID. All in the same row.:
NEW TABLE I NEED TO CREATE
ID STRING DATA Name Feb READY
1 ABC READ Deven 12 OK
2 CDE WRITE NO
3 FGH READ OK
4 HSS WRITE Monish 21
5 FFH WRITE Ritesh 22
Which comand Have I to use?
Please be patient because I’m a newbe of sql language.
Thank you very much
Basically, you want a big left outer join starting with the first table (based on your sample data):
select t1.id, t1.string, t1.data, t2.name, t2.feb, t3.ready
from table1 t1 left join
table2 t2
on t1.id = t2.id left join
table3 t3
on t1.id = t3.id;
It is impossible to tell from your sample data if the id is the only (or right) join key. However, you should (and need to) know the relationships between the tables in order to create the correct query.
If you want this in a table, just pre-pend the create table as statement before the select.
Create a view which has the fields that you want. Then execute INSERT INTO ... SELECT * FROM view ....

MS Access VBA: Combine 2 SQL statements with a LEFT JOIN

Hi all and thanks in advance for your help!
I am trying to use a JOIN to combine a fitlered SQL statement with a table in order to populate a combobox (makes sense?)
Here is the main SQL query:
MainSQLquery = "SELECT QuotationID, QuoteDate, EmployeeID FROM TestTable1"
I want to write a statement to use this with another table like so:
SELECT EmployeeID, EmployeeName
FROM MainSQLquery LEFT JOIN EmployeeTable
GROUP BY EmployeeID
But I can't get it right. I get a "Syntax error in FROM clause" even with something as simple as:
ComboSQL = "SELECT EmployeeID FROM " & MainSQLQuery
Me.Combo2.RowSource = ComboSQL
Do you guys know any way to do this?
*******BACKGROUND**********
For those of you who wants to see the bigger picture, I have a subform showing a list of quotations and based on a dynamic SQL statement, it is filetered with a WHERE clause based on different inputs and it looks like this when displayed:
QuoteID Quote date Employee ID
1 10/13 1
2 10/13 2
3 10/13 2
4 09/18 1
5 08/10 2
6 07/16 3
7 06/27 3
On the main form, I have comboboxes that I use to filter this subform, which works perfectly. But I also need my comboboxes to be filtered the same way as the subform content and without having any duplicate (that's the only thing I can't do right now).
So far I use the same filtered SQL query for the subform and all the comboboxes, so instead of having a neat Employee combobox that looks like this (with the example above):
1
2
3
I get that instead (same as the subform):
1
2
2
1
2
3
3
My idea is to have a main SQL query for the subform, and another SQLquery based on the main one for the comboboxes, something like that:
SELECT EmployeeID, EmployeeName
FROM MainSQLquery LEFT JOIN EmployeeTable
GROUP BY EmployeeID
if I could get this working, the filter would still be built in the mainSQL and I could group the EmployeeID field without problem.
I guess it should be fairly simple, but I can't get it right, there is something I don't know about using an SAL as source of another.
(I wish I could post pictures or a database sample, but a paranoid guy got my previous post deleted because of that, so it will have to do with text only, sorry about that)
When you have a JOIN you should have an ON to let the database know how to relate the tables:
SELECT EmployeeID, EmployeeName
FROM (
SELECT QuotationID, QuoteDate, EmployeeID
FROM TestTable1
) AS MainSQLquery LEFT JOIN EmployeeTable
ON MainSQLquery.EmployeeID = EmployeeTable.ID
GROUP BY EmployeeID
The LEFT JOIN gets all records from the table on the left of the join -- MainSQLquery -- and only the records from the right table -- EmployeeTable -- that match. If no matches are found in the right table, a NULL value is returned.
Given this example:
TestTable1
QuotationID | QuoteDate | EmployeeID
--------------------------------------------
1 10/1/2014 1
2 10/8/2014 2
3 10/5/2014 3
4 10/10/2014 1
5 10/20/2014 5
EmployeeTable
ID | EmployeeName
----------------------
1 Jeremy Smith
2 Pam Engles
3 Achim Flemmish
4 Sandra Hayes
This would be the result of the above query:
Result
EmployeeID | EmployeeName
--------------------------------
1 Jeremy Smith
2 Pam Engles
3 Achim Flemmish
5 NULL