SQL Self Join - one to many - with dates - sql

I have the following two tables in sqlite:
SQL Tables
The table "Performance Indicator Table" gets populated each day with 'PerformanceIndicator' values from previous day against each site. Each site is connected to many other sites termed as site's neighbors. For instance, site A may have site C and D as its neighbors. Similarly site C can have B and itself as neighbors. These neighbor relations are defined in a mostly static "Neighbor Table".
I need to come up with a single view, joining the two tables such that we have:
Resultant Table
Please help me in coming up with the required SQL. I thought of the following:
select neighbors.site, neighbors.neighbor, PI_Table.*
from neighbors
inner join PI_Table
on neighbors.neighbor = PI_Table.site;
I am using Sqliteman to process the query and this gives me some kind of result. But exporting results in Sqliteman not responding. This may be due to number of rows. Number of rows should be:
Number of rows in resultant view
Please let me know if it seems okay and sorry for not being able to have the images in-line.

select neighbors.site, neighbors.neighbor,
p1.*, p2.*,
performance(..)
from neighbors
inner join PI_Table p1
on neighbors.site = p1.site;
inner join PI_Table p2
on neighbors.neighbor = p2.site;
AND p1.date = p2.date

Related

Inner joining two tables returns empty result

I am trying to get two tables that aren't related to pull a column of data each.
I have one table called AlphaData and one called TLAuth. Each includes a column that is labelled invoice and I need to pull both columns so I can at least start a comparison. TLAuth will include some of the invoice numbers from AlphaData, but not all of them.
Right now I am using the following code:
SELECT Alphadata.Invoice, TLAuth.Invoice
FROM Alphadata
INNER JOIN TlAuth
ON TLauth.TLAUthID = Alphadata.TLAUthID;
But every time I run this it comes up totally blank. There is definitely data in there, I can pull one column of data from each, but not both at the same time. I have even setup a relationship (1 to Many from TL Auth to Alphadata) and it doesn't seem to work so any help would be grand.
If the tables could not match you should use left join
SELECT Alphadata.Invoice, TLAuth.Invoice
From Alphadata
LEFT JOIN TlAuth ON TLauth.TLAUthID=Alphadata.TLAUthID;

SQL Query Results Using Joins

I'm trying to do this query to display the names of the stores and the quantity of each book sold with only using joins but I tried to use
SELECT DISTINCT x.stor_name, t.title, s.qty
FROM stores x
INNER JOIN discounts d
ON x.stor_id=d.stor_id
INNER JOIN salesdetail s
ON d.stor_id=s.stor_id
INNER JOIN titles t
ON s.title_id=t.title_id
ORDER BY s.qty desc;
but that only displayed one of the stores results set for 'Bookbeat'.
I tried to use Left, Right & Full Outer joins to no avail so I'm wondering how I would go about doing that query to display the names for the other stores that are not displaying their result set. As there is 7 stores and only 1 is displaying it's results.
The link is a pastebin to the database.
And this is the schema.
It's hard to say without more information about your schema - it strikes me as wrong-ish that you're joining to discounts only on stor_id. I'd expect discounts to be applied to different titles, not store-wide... and I wouldn't expect discounts to be always-enabled. Try running it without the discounts inner join. Futzing around with "Distinct" and outer joins is almost always the wrong approach with things like this
I see from your profile you're a first-year. Is this schoolwork? How do I ask and answer homework questions?

Multiple JOIN statements returning multiple rows

I believe I need a fresh set of eyes, my attention has been pulled elsewhere at work and I have not had the time to figure this out. So I'm hoping someone may be kind enough to offer a suggestion.
Here is an abbreviated version of my SQL statement:
SELECT
PR.PROJECTNUM,
PR.PROJECTNUMBER,
PR.AMRNUM,
W.WONUM,
C.PONUM,
C.POLINENUM
FROM PROJECT PR
INNER JOIN WORKORDER W
ON PR.PROJECTNUM = W.PROJECTNUM
OR PR.PROJECTNUMBER = W.PROJECTNUMBER
OR PR.AMRNUM = W.AMRNUM
INNER JOIN
(SELECT PL.WONUM, P.PONUM, PL.POLINENUM FROM PO P
INNER JOIN POLINE PL ON P.PONUM = PL.PONUM) C
ON W.WONUM = C.WONUM;
As you can see, I'm joining 4 tables here.PO to POLINE to WORKORDER to PROJECT. The issue lies with the multiple joining attributes between the WORKORDER and PROJECT table.
I do not know beforehand which attribute/field will be populated with a value in the WORKORDER table, but at least one will be...but sometimes all three. The duplication occurs when more than one of the joining attributes in the WORKORDER table is populated with a matching value in the PROJECT table.
It's almost as if I need to test for the presence of a value in the joining attribute from the WORKORDER table before I execute the above SQL....and if more than one is populated with a value, then I need to find which one of the PROJECTattributes has a matching value....geez...even typing it out is making my head spin...lol
I may need to come back in the morning and add a little more context, my brain is fried at the moment :)
Thanks for reading!

SQL Query, return all children in a one-to-many relationship when one child matches

I'm working on enhancing a query for a DB2 database and I'm having some problems getting acceptable performance due to the number of joins across large tables that need to be performed to get all of the data and I'm hoping that there's a SQL function or technique that can simplify and speed up the process.
To break it down, let's say there are two tables: People and Groups. Groups contain multiple people, and a person can be part of multiple groups. It's a many-to-many, but bear with me. Basically, there's a subquery that will return a set of groups. From that, I can join to People (which requires additional joins across other tables) to get all of the people from those groups. However, I also need to know all of the groups that those people are in, which means joining back to the Groups table again (several more joins) to get a superset of the original subquery. There are additional joins in the query as well to get other pieces of relevant data, and the cost is adding up in a very ugly way. I also need to return information from both tables, so that rules out a number of techniques.
What I'd like to do is be able to start with the People table, join it to Groups, and then compare Groups with the subquery. If the Groups attached to one person has one match in the subquery, it should return ALL Group items associated with that person.
Essentially, let's say that Bob is part of Group A, B, and C. Currently, I start with groups, and let's say that only Group A comes out of the subquery. Then I join A to Bob, but then I have to come back and join Bob to Group again to get B and C. SQL example:
SELECT p.*, g2.*
FROM GROUP g
JOIN LINKA link
ON link.GROUPID = g.GROUPID
JOIN LINKB link1
ON link1.LISTID = link.LISTID
JOIN PERSON p
ON link1.PERSONID = p.PERSONID
JOIN LINKB link2
ON link2.PERSONID = p.PERSONID
JOIN LINKA link3
ON link2.LISTID = link3.LISTID
JOIN GROUP g2
ON link3.GROUPID = g2.GROUPID
WHERE
g.GROUPID IN (subquery)
Yes, the linking tables aren't ideal, but they're basically normalized tables containing additional information that is not relevant to the query I'm running. We have to start with a filtered Group set, join to People, then come back to get all of the Groups that the People are associated to.
What I'd like to do is start with People, join to Group, and if ANY Group that Bob is in returns from the subquery, ALL should be returned, so if we have Bob joined to A, B, and C, and A is in the subquery, it will return three rows of Bob to A, B, and C as there was at least one match. In this way, it could be treated as a one-to-many relationship if we're only concerned with the Groups for each Person and not the other way around. SQL example:
SELECT p.*, g.*
FROM PEOPLE p
JOIN LINKB link
ON link.PERSONID = p.PERSONID
JOIN LINKA link1
ON link.LISTID = link1.LISTID
JOIN GROUP g
ON link1.GROUPID = g.GROUPID
WHERE
--SQL function, expression, or other method to return
--all groups for any person who is part of any group contained in the subquery
The number of joins in the first query make it largely unusable as these are some pretty big tables. The second would be far more ideal if this sort of thing is possible.
From the question, I think you are querying hierarchical data. DB2 provides facility to deal with such data. There are two clauses Start with and Connect by in DB2 which will be useful. They are explained here.

Inner join sql statement

I have two tables, Invoices and members, connected by PK/FK relationship through the field InvoiceNum. I have created the following sql and it works fine, and pulls 44 records as expected.
SELECT
INVOICES.InvoiceNum,
INVOICES.GroupNum,
INVOICES.DivisionNum,
INVOICES.DateBillFrom,
INVOICES.DateBillTo
FROM INVOICES
INNER JOIN MEMBERS ON INVOICES.InvoiceNum = MEMBERS.InvoiceNum
WHERE MEMBERS.MemberNum = '20032526000'
Now, I want to replace INVOICES.GroupNum and INVOICES.DivisionNum in the above query with GroupName and DivisionName. These values are present in the Groups and Divisions tables which also have the corresponding Group_num and Division_num fields. I have created the following sql. The problem is that it now pulls 528 records instead of 44!
SELECT
INVOICES.InvoiceNum,
INVOICES.DateBillFrom,
INVOICES.DateBillTo,
DIVISIONS.DIVISION_NAME,
GROUPS.GROUP_NAME
FROM INVOICES
INNER JOIN MEMBERS ON INVOICES.InvoiceNum = MEMBERS.InvoiceNum
INNER JOIN GROUPS ON INVOICES.GroupNum = GROUPS.Group_Num
INNER JOIN DIVISIONS ON INVOICES.DivisionNum = DIVISIONS.Division_Num
WHERE MEMBERS.MemberNum = '20032526000'
Any help is greatly appreciated.
You have at least one relation between your tables which is missing in your query. It gives you extra records. Find all common fields. Say, are divisions related to groups?
The statement is fine, as far as the SQL syntax goes.
But the question you have to ask yourself (and answer it):
How many rows in Groups do you get for that given GroupNum?
Ditto for Divisions - how many rows exist for that DivisionNum?
It would appear that those numbers aren't unique - multiple rows exist for each number - therefore you get multiple rows returned