Joining two tables in QlikView - qlikview

Need to join CountPerCategory from resident table after applying count function to another table (FACT)
FOR Each vsheet2 IN 'D','H','Q'
FACT:
LOAD
RowNo() as ID,
ProfileReceivedDate,
"SkillCategory ";
SQL SELECT
ProfileReceivedDate,
"SkillCategory "
FROM .dbo.$(vsheet2);
NEXT
FOR Each vsheet3 In 'D','H','Q'
SKILL_CATEGORIES:
LOAD
"SkillCategory ";
SQL SELECT
"SkillCategory "
FROM Ndbo.$(vsheet3);
NEXT
JOIN (vsheet2):
countSkill:
Load
Count("SkillCategory ") as CountPerCategory
Resident
SKILL_CATEGORIES
Group by
"SkillCategory "
;

Left join the secondary table to the FACT table via LEFT JOIN([Table Name]) and ensure you apply the "SkillCategory " field to the GROUP BY also if that is how you are linking the values.
Thanks
FOR Each vsheet2 IN 'D','H','Q'
FACT:
LOAD
RowNo() as ID,
ProfileReceivedDate,
"SkillCategory ";
SQL SELECT
ProfileReceivedDate,
"SkillCategory "
FROM .dbo.$(vsheet2);
NEXT
FOR Each vsheet3 In 'D','H','Q'
SKILL_CATEGORIES:
LOAD
"SkillCategory ";
SQL SELECT
"SkillCategory "
FROM Ndbo.$(vsheet3);
NEXT
LEFT JOIN(FACT)
Load
"SkillCategory ",
Count("SkillCategory ") as CountPerCategory
Resident
SKILL_CATEGORIES
Group by
"SkillCategory ";

Related

PostgreSQL joining multiple tables

Hi guys I am trying to join tables here, I want to add table called Table2 so that students from that table are displayed too. The thing which is confusing is I already have joins in this query, so how should add another join so that students from that Table2 are displayed as well, without breaking the existing code . Also, there is no way I can check output
The ID varables are stsidno in stTable 1, sidno in Table2, scsidno in table schedprd
Here's the code:
String selS = "select distinct stdistrict,stschool,stsidno,"
+ " sname as name,stgrade,"
+ "S.recnum as recnum, S.stldate as stldate,scsec,sctea,sccor,scgrade,scclsprd,scgrdprd,"
+ "case when P.scchangestartdate is null then C.clstart else "
+ "P.scchangestartdate end as scchangestartdate, "
+ "case when S.stedate is null or S.stedate<C.clstart "
+ "then C.clstart else S.stedate end as stedate "
+ "from stTable1 as S join schedprd as P on "
+ "(scyear=styear and scdistrict=stdistrict and scschool=stschool "
+ "and stsidno=scsidno and (scsec is not null and scsec<>'')) "
+ "left outer join calendar as C on (C.clyear=S.styear and "
+ "C.cldistrict=S.stdistrict and C.clschool=S.stschool and C.cltype='10') "
+ "where styear=? and stdistrict=? ";
You could UNION Table1 and Table2 together in a Common Table Expression (CTE) and then reference the CTE instead of Table1 in your query, like below:
WITH CTE
AS
(
SELECT *
FROM Table1
UNION
SELECT *
FROM Table2
)
select distinct
stdistrict,
stschool,
stsidno,
sname as name,
stgrade,
S.recnum as recnum,
S.stldate as stldate,
scsec,
sctea,
sccor,
scgrade,
scclsprd,
scgrdprd,
case when P.scchangestartdate is null then C.clstart else P.scchangestartdate end as scchangestartdate,
case when S.stedate is null or S.stedate<C.clstart then C.clstart else S.stedate end as stedate
from CTE as S
join schedprd as P on (scyear=styear and scdistrict=stdistrict and scschool=stschool and stsidno=scsidno and (scsec is not null and scsec<>''))
left outer join calendar as C on (C.clyear=S.styear and C.cldistrict=S.stdistrict and C.clschool=S.stschool and C.cltype='10')
where styear=? and stdistrict=?;

Sql Joins on multiple table returning product of two columns

I am trying to generate a report on a sql server database in asp.net and I am getting the results of some columns as a product of two columns. Here is the code
comm.CommandText = "SELECT Count(Courses.CourseID) AS CourseCount, Count(Students.StudentID) AS StudentCount, Schools.Name, Schools.StartDate, Schools.SchoolFees " +
"FROM Schools" +
"LEFT JOIN Courses ON (Schools.SchoolID = Courses.SchoolID)" +
"LEFT JOIN Students ON (Schools.SchoolID = Students.SchoolID) " +
"WHERE Schools.Active = 1 " +
"GROUP BY Schools.Name, Schools.StartDate, Schools.SchoolFees";
When I run the code, the result displays, but the columns for "CourseCount" and "StudentCount" display a value that is a product of each individual column. "CourseCount" is normally 288 and "StudentCount" is 38 but when I run the code, both "CourseCount" and "StudentCount" display 10944 which is 38 x 288.
Anyway I can make them display the correct values?
Changing your code from using a count of all rows, to a count of distinct values only, should return the results you expect
comm.CommandText = "SELECT Count(DISTINCT Courses.CourseID) AS CourseCount, Count(DISTINCT Students.StudentID) AS StudentCount, Schools.Name, Schools.StartDate, Schools.SchoolFees " +
"FROM Schools" +
"LEFT JOIN Courses ON (Schools.SchoolID = Courses.SchoolID)" +
"LEFT JOIN Students ON (Schools.SchoolID = Students.SchoolID) " +
"WHERE Schools.Active = 1 " +
"GROUP BY Schools.Name, Schools.StartDate, Schools.SchoolFees";
The results being returned are technically correct, if all schools have courses, and all courses have students
As stated above, it is how you are using the COUNT (), You are asking it to count all, which is why it returns so many. Use count on just the two values you want counted.
This might perform better than the DISTINCT Count method..
comm.CommandText =
"SELECT cc.CourseCount, sc.StudentCount, Schools.Name, Schools.StartDate, Schools.SchoolFees " +
"FROM Schools" +
"OUTER APPLY (SELECT Count(Students.StudentID) StudentCount FROM Students WHERE Students.SchoolID = Schools.SchoolID) sc " +
"OUTER APPLY (SELECT Count(Courses.CourseID) CourseCount FROM Courses WHERE Courses.SchoolID = Schools.SchoolID) cc " +
"WHERE Schools.Active = 1 ";

Insert Into SQL VBA

I am trying to select records that are in the first table but not in the second table and insert them into the second table using a sql statement in VBA. I have started it below but I am not sure why it won't work. I am rather new to sql so any help would be greatly appreciated.
MySQL = "INSERT INTO Clients ()" & _
"SELECT DISTINCT DD.[Client ID] " & _
"FROM " & tableName & " as DD " & _
"Where DD.[Client ID] NOT IN (SELECT DD.[Client ID] FROM " & tableName & " as DD)"
First, you need supply field list to insert statement:
INSERT INTO Clients (ClientID)...
Second, your query doesn't insert any rows, because you check ClientID presence in same table. Did you mean someting like next:
"Where DD.[Client ID] NOT IN (SELECT DD2.[Client ID] FROM " & tableName2 & " as DD2)"

SQL returning the count from wrong table

This SQL is returning the record count of table Dims instead returning the record count of table BIDdetails. How can I fix?
BIDReportSearch.CommandText = ("SELECT BIDdetails.Origin, BIDdetails.Destination,
Round(Sum(Dims.ChargeableWeight)) as CWeight, count(BIDdetails.Origin) as NoOfShpt
FROM BIDdetails LEFT JOIN DIMS ON BidDetails.BID=Dims.BID
where BIDdetails.OrgCountry<>'AE' and BIDdetails.DestCountry='AE' and
BIDdetails.ClosingDate>=#" & dtpBIDfrom.Value & "# and BIDdetails.ClosingDate<=#" &
dtpBIDto.Value & "# GROUP BY BIDdetails.Origin, BIDdetails.Destination
ORDER BY Round(Sum(Dims.ChargeableWeight)) DESC")
The expression:
count(BIDdetails.Origin)
simply counts the number of non-NULL values of BIDdetails.Origin in each group. Because you are actually grouping by the field, that would be the number of rows in each group.
You can get what you want in most databases by using count(distinct) on a unique identifier. Alas, MS Access doesn't support count(distinct) so such a query is much harder to write in Access. You can get just the count field by doing:
SELECT BIDdetails.Origin, BIDdetails.Destination, count(*) as NoOfShpt
FROM BIDdetails
where BIDdetails.OrgCountry <> 'AE' and BIDdetails.DestCountry='AE' and
BIDdetails.ClosingDate>=#" & dtpBIDfrom.Value & "# and BIDdetails.ClosingDate<=#" & dtpBIDto.Value & "#
GROUP BY BIDdetails.Origin, BIDdetails.Destination;
And then combining the results either in your application or by joining this query back into the original one.
EDIT:
This is your original query:
SELECT d.Origin, d.Destination,
Round(Sum(Dims.ChargeableWeight)) as CWeight, count(d.Origin) as NoOfShpt
FROM BIDdetails as d LEFT JOIN
DIMS
ON BidDetails.BID=Dims.BID
where d.OrgCountry <> 'AE' and d.DestCountry='AE' and
d.ClosingDate> = #" & d.Value & "# and d.ClosingDate<=#" & dtpBIDto.Value & "#
GROUP BY d.Origin, d.Destination
ORDER BY Round(Sum(Dims.ChargeableWeight)) DESC
There is another approach, where you aggregate first by the details and then again. I think that is easier in this case:
SELECT Origin, Destination, SUM(CWeight) as CWeight, COUNT(*) as NumShip
FROM (SELECT d.id, d.Origin, d.Destination,
Round(Sum(Dims.ChargeableWeight)) as CWeight, count(d.Origin) as NoOfShpt
FROM BIDdetails as d LEFT JOIN
DIMS
ON BidDetails.BID = Dims.BID
where d.OrgCountry <> 'AE' and d.DestCountry='AE' and
d.ClosingDate> = #" & d.Value & "# and d.ClosingDate<=#" & dtpBIDto.Value & "#
GROUP BY d.id, d.Origin, d.Destination
) as d
GROUP BY Origin, Destination
ORDER BY Round(Sum(CWeight)) DESC;
d.id refers to whatever the unique id is for what you want to count.

Update record if matching values in same table

I have a MS Access database with a list of transactions. I am trying to update a "Match" field on both records where they have some of the same values in fields (Document Number, Voucher Number, Subhead) but opposite amounts. It also needs to avoid duplicates.
Document Number Amount ABS Match
N6809561990112 438.48 438.48
N6809561990112 438.48 438.48
N6809561990112 -438.48 438.48
What I the end result after the SQL should look like
Document Number Amount ABS Match
N6809561990112 438.48 438.48 Y
N6809561990112 438.48 438.48
N6809561990112 -438.48 438.48 Y
The table name is "tblUnmatched"
I tried the following but it updated every record in the table to "Y"
strSql = "Update tblUnmatched SET match = 'Y' WHERE EXISTS(select * " & _
"from tblUnmatched t1 " & _
"inner join tblUnmatched t2 on " & _
"t1.[DOCUMENT NUMBER] = t2.[DOCUMENT NUMBER]" & _
"where t1.ABS = t2.ABS AND t1.AMOUNT <> t2.AMOUNT AND t1.SUBH = t2.SUBH)"
DoCmd.RunSQL strSql
I also tried this but it couldn't handle the duplicate problem.
strSql = "Update tblUnmatched SET match = 'Y' WHERE [DOCUMENT NUMBER] IN(select t1.[DOCUMENT NUMBER] " & _
"from tblUnmatched t1 " & _
"inner join tblUnmatched t2 on " & _
"t1.[DOCUMENT NUMBER] = t2.[DOCUMENT NUMBER]" & _
"where t1.ABS = t2.ABS AND t1.AMOUNT <> t2.AMOUNT AND t1.SUBH = t2.SUBH)"
DoCmd.RunSQL strSql
Your task is impractical in Access SQL without a primary key field. Although there is no such key in the data source you import, that does not prohibit you from adding one in Access.
Add an autonumber primary key, id, to tblUnmatched. Then for each new batch of incoming data:
import into a scratch table, tblScratch
DELETE FROM tblUnmatched
append the rows from tblScratch into tblUnmatched
(The process could be cleaner if you can use SELECT FROM <your data source> to append directly to tblUnmatched, instead of first importing to tblScratch.)
Save the following SELECT statement as qryFindMatches:
SELECT
sub.[Document Number],
sub.Amount,
sub.MinOfid,
DCount(
"*",
"tblUnmatched",
"[Document Number]='" & [Document Number]
& "' AND Amount = -1 * " & [Amount]
) AS match_count
FROM
(
SELECT [Document Number], Amount, Min(id) AS MinOfid
FROM tblUnmatched
GROUP BY [Document Number], Amount
) AS sub;
Then the UPDATE you want can be fairly easy to create. Beware the performance may not be blazing fast; hopefully you can accommodate it once a month.
UPDATE tblUnmatched
SET [Match] = True
WHERE id In
(
SELECT MinOfId
FROM qryFindMatches
WHERE match_count > 0
);
I added an additional row to your sample data and tested with Access 2007. I think this is what you want ...
id Document Number Amount Match
1 N6809561990112 $438.48 True
2 N6809561990112 $438.48 False
3 N6809561990112 ($438.48) True
4 N6809561990112 $5.00 False