SELECT DISTINCT 'DATA' AS DSN,
'MASTER' AS ORG_ID,e.emp_id,
e.emp_name AS EMPLOYEE_NUMBER,
e.emp_firstname AS EMPLOYEE_FIRST_NAME,
e.emp_lastname AS EMPLOYEE_LAST_NAME,
e.emp_val20 AS PAY_STATUS,
(NVL(TO_CHAR(PGT.PAYGRPTYP_NAME),'MASTER')) AS PAY_FREQUENCY,
E.EMP_VAL16 AS PAY_CLASS,
SP.SHFTPAT_NAME AS SHIFT_CODE,
WB.WBU_EMAIL AS EMAIL_ADDR,
(NVL(TO_CHAR( DE.DEPT_NAME),'MASTER')) AS DEPARTMENT,
NULL AS HELD_POSTN,
(NVL(TO_CHAR( J.JOB_NAME),'MASTER')) AS JOB_TITLE,
WB. WBU_NAME AS USER_NAME,
(NVL(TO_CHAR(ET.WBT_ID ),'MASTER')) AS TEAM_CODE,
WT.WBT_NAME AS TEAM_NAME,
WT.WBT_DESC AS TEAM_DESC,
(NVL(TO_CHAR(EB.EMPBDG_BADGE_NUMBER),'MASTER')) AS PERMANENT_BADGE_NO
FROM EMPLOYEE E
LEFT JOIN SHIFT_PATTERN SP
ON E.SHFTPAT_ID =SP.SHFTPAT_ID
LEFT JOIN PAY_GROUP PT
ON E.PAYGRP_ID =PT.PAYGRP_ID
LEFT JOIN PAY_GROUP_TYPE PGT
ON PT.PAYGRPTYP_ID =PGT.PAYGRPTYP_ID
LEFT JOIN EMPLOYEE_BADGE EB
ON E.EMP_ID=EB.EMP_ID
LEFT JOIN EMP_UDF_DATA ED
ON E.EMP_ID=ED.EMP_ID
LEFT JOIN WORKBRAIN_USER WB
ON E.EMP_ID=WB.EMP_ID
LEFT JOIN EMP_DEF_LAB D
ON E.EMP_ID=D.EMP_ID
LEFT JOIN DEPARTMENT DE
ON D.DEPT_ID=DE.DEPT_ID
LEFT JOIN EMPLOYEE_JOB EJ
ON E.EMP_ID=EJ.EMP_ID
LEFT JOIN JOB J
ON EJ.JOB_ID=J.JOB_ID
LEFT JOIN EMPLOYEE_TEAM ET
ON E.EMP_ID=ET.EMP_ID
LEFT JOIN WORKBRAIN_TEAM WT
ON ET.WBT_ID=WT.WBT_ID
LEFT JOIN CALC_GROUP CG
ON E.CALCGRP_ID =CG.CALCGRP_ID
WHERE E.EMP_ID NOT IN (SELECT EMP_ID FROM EMPLOYEE_READER_GROUP)
AND sysdate BETWEEN ET.empt_start_date AND ET.empt_end_date
AND ET.empt_home_team = 'Y'
AND sysdate BETWEEN EJ.EMPJOB_START_DATE AND EJ.EMPJOB_END_DATE
GROUP BY E.EMP_ID,
-- ER.rdrgrp_id,
e.emp_name,
e.emp_lastname,
e.emp_firstname,
e.emp_status,
e.emp_val20,
PGT.PAYGRPTYP_NAME,
E.EMP_VAL16,
e.EMP_VAL18,
EB.EMPBDG_BADGE_NUMBER,
WB.WBU_EMAIL,
DE.DEPT_NAME,
J.JOB_NAME,
SP.SHFTPAT_NAME,
WB. WBU_NAME ,
ET.WBT_ID ,
WT.WBT_NAME,
WT.WBT_DESC;
I want all data from employee table so i used left join but i am not getting all rows which is available in employee table some values are missing .Please help me with this . I have 43000 rows in employee but when i am using this i am getting only 17000 rows alone. I am not sure where i am lagging.I want the null column as Master for the right table values.
Think of the data you want in sets. When you LEFT JOIN, you're joining the whole tables when you really only need data from one of them. I've modified a few of your LEFT JOINS to factor for this. Also, doing a WHERE x NOT IN (SELECT x....) can be VERY slow on large datasets. I've changed it to allow the optimizer to work a little better. It now does a LEFT JOIN....WHERE x IS NULL. This should work a lot faster. What do you plan on MAXing? This query is pretty involved. You want to make sure you're getting the initial data that you want before you try to aggregate it.
SELECT 'DATA' AS DSN,
'MASTER' AS ORG_ID,e.emp_id,
e.emp_name AS EMPLOYEE_NUMBER,
e.emp_firstname AS EMPLOYEE_FIRST_NAME,
e.emp_lastname AS EMPLOYEE_LAST_NAME,
e.emp_val20 AS PAY_STATUS,
(NVL(TO_CHAR(ptpgt.PAYGRPTYP_NAME),'MASTER')) AS PAY_FREQUENCY, /* From subquery join */
E.EMP_VAL16 AS PAY_CLASS,
SP.SHFTPAT_NAME AS SHIFT_CODE,
WB.WBU_EMAIL AS EMAIL_ADDR,
(NVL(TO_CHAR( DE.DEPT_NAME),'MASTER')) AS DEPARTMENT,
NULL AS HELD_POSTN,
(NVL(TO_CHAR( eej.JOB_NAME),'MASTER')) AS JOB_TITLE, /* From subquery join */
WB. WBU_NAME AS USER_NAME,
(NVL(TO_CHAR(eet.WBT_ID ),'MASTER')) AS TEAM_CODE, /* From subquery join */
WT.WBT_NAME AS TEAM_NAME,
WT.WBT_DESC AS TEAM_DESC,
(NVL(TO_CHAR(EB.EMPBDG_BADGE_NUMBER),'MASTER')) AS PERMANENT_BADGE_NO
FROM EMPLOYEE E
/* This plus WHERE ERG.EMP_ID IS NULL is the same as the subquery filter. But faster. */
LEFT OUTER JOIN EMPLOYEE_READER_GROUP erg ON e.EMP_ID = ERG.EMP_ID
LEFT JOIN SHIFT_PATTERN SP ON E.SHFTPAT_ID =SP.SHFTPAT_ID
LEFT JOIN (
SELECT PT.EMP_ID,PGT.PAYGRPTYP_NAME
FROM PAY_GROUP PT
INNER JOIN PAY_GROUP_TYPE PGT ON PT.PAYGRPTYP_ID =PGT.PAYGRPTYP_ID
) ptpgt ON E.PAYGRP_ID =ptpgt.PAYGRP_ID
LEFT JOIN EMPLOYEE_BADGE EB ON E.EMP_ID=EB.EMP_ID
LEFT JOIN EMP_UDF_DATA ED ON E.EMP_ID=ED.EMP_ID
LEFT JOIN WORKBRAIN_USER WB ON E.EMP_ID=WB.EMP_ID
LEFT JOIN (
SELECT D.EMP_ID, DE.DEPT_NAME
FROM EMP_DEF_LAB D
INNER JOIN DEPARTMENT DE ON D.DEPT_ID=DE.DEPT_ID
) dde ON E.EMP_ID=dde.EMP_ID
LEFT JOIN (
SELECT EJ.EMP_ID, J.JOB_NAME
FROM EMPLOYEE_JOB EJ
INNER JOIN JOB J ON EJ.JOB_ID=J.JOB_ID
WHERE sysdate BETWEEN EJ.EMPJOB_START_DATE AND EJ.EMPJOB_END_DATE
/*
Doublecheck your date filters. Are they getting the edge dates you need?
BETWEEN makes it easy to miss a date, especially if your fields
are DATETIME datatypes.
USE <=/>= to be a bit clearer.
*/
) eej ON E.EMP_ID=eej.EMP_ID
LEFT JOIN (
SELECT ET.EMP_ID, WBT_ID
FROM EMPLOYEE_TEAM ET
INNER JOIN WORKBRAIN_TEAM WT ON ET.WBT_ID=WT.WBT_ID
WHERE
ET.empt_home_team = 'Y'
AND sysdate BETWEEN ET.empt_start_date AND ET.empt_end_date
/*
Doublecheck your date filters. Are they getting the edge dates you need?
BETWEEN makes it easy to miss a date, especially if your fields
are DATETIME datatypes.
USE <=/>= to be a bit clearer.
*/
) eet ON E.EMP_ID=eet.EMP_ID
LEFT JOIN CALC_GROUP CG ON E.CALCGRP_ID=CG.CALCGRP_ID
WHERE
ERG.EMP_ID IS NULL
You can LEFT join all day long, your where clause is still going to function as a filter. Try it with no where clause and see if you get all 43k. Plus you are grouping which could be collapsing rows.
These filters in the WHERE clause turn the OUTER JOIN into an INNER JOIN:
AND sysdate BETWEEN ET.empt_start_date AND ET.empt_end_date
AND ET.empt_home_team = 'Y'
AND sysdate BETWEEN EJ.EMPJOB_START_DATE AND EJ.EMPJOB_END_DATE
Because they exclude rows where the tested attributes are null (which is what they are in a non-matched outer-joined row).
So there are a couple of approaches. The first is to allow for nulls, e.g.
AND ( ET.empt_home_team is null or
( sysdate BETWEEN ET.empt_start_date AND ET.empt_end_date
AND ET.empt_home_team = 'Y' )
)
AND ( EJ.EMPJOB_START_DATE is null
or sysdate BETWEEN EJ.EMPJOB_START_DATE AND EJ.EMPJOB_END_DATE )
The second is to replace the tables with inline views e.g.
LEFT JOIN ( select * from EMPLOYEE_TEAM
where sysdate BETWEEN empt_start_date AND empt_end_date
AND empt_home_team = 'Y' ) ET
ON E.EMP_ID=ET.EMP_ID
LEFT JOIN ( select * from EMPLOYEE_JOB
where sysdate BETWEEN EMPJOB_START_DATE AND EMPJOB_END_DATE ) EJ
ON E.EMP_ID=EJ.EMP_ID
Which approach is the better one for you depends on the data. test them and see.
Related
I have this query below for oracle sql:
SELECT
/*+parallel(4)*/
TO_CHAR (a.Po_Distribution_Id) AS INTEGRATION_ID,
MIN(c.NEED_BY_DATE) AS X_ORIG_NEED_BY_DT,
b.PROMISED_DATE AS X_PROMISED_DT,
MIN(c.PROMISED_DATE) AS X_ORIG_PROMISED_DT,
COALESCE(b.PROMISED_DATE,b.NEED_BY_DATE) AS X_NEED_BY_DT
FROM PO_DISTRIBUTIONS_ALL a
LEFT OUTER JOIN PO_LINE_LOCATIONS_ALL b
ON a.LINE_LOCATION_ID=b.LINE_LOCATION_ID
LEFT OUTER JOIN PO_LINE_LOCATIONS_ARCHIVE_ALL c
ON c.LINE_LOCATION_ID=b.LINE_LOCATION_ID
AND a.CREATION_DATE >= '30-SEP-2017'
and rownum = 10
GROUP BY a.Po_Distribution_Id,
b.PROMISED_DATE,
b.PROMISED_DATE,
b.NEED_BY_DATE
When i execute it, i got ORA-01417: a table may be outer joined to at most one other table. Need help for this error.
Please use below query. In the current query, your aggregation is incorrect, you have to use same function as you use in the select query. And changed the filter criteria to WHERE instead of AND. Also not sure why you are selecting rownum=10,it will provide you only one record. Is that fine?
SELECT
/*+parallel(4)*/
TO_CHAR (a.Po_Distribution_Id) AS INTEGRATION_ID,
MIN(c.NEED_BY_DATE) AS X_ORIG_NEED_BY_DT,
b.PROMISED_DATE AS X_PROMISED_DT,
MIN(c.PROMISED_DATE) AS X_ORIG_PROMISED_DT,
COALESCE(b.PROMISED_DATE,b.NEED_BY_DATE) AS X_NEED_BY_DT
FROM PO_DISTRIBUTIONS_ALL a
LEFT OUTER JOIN PO_LINE_LOCATIONS_ALL b
ON a.LINE_LOCATION_ID=b.LINE_LOCATION_ID
LEFT OUTER JOIN PO_LINE_LOCATIONS_ARCHIVE_ALL c
ON c.LINE_LOCATION_ID=b.LINE_LOCATION_ID
WHERE a.CREATION_DATE >= '30-SEP-2017'
and rownum = 10
GROUP BY TO_CHAR (a.Po_Distribution_Id),
b.PROMISED_DATE
COALESCE(b.PROMISED_DATE,b.NEED_BY_DATE);
I am converting following oracle query to bigquery query but the results(record counts) are different, eventhough base tables involved in the query are having same number of records in both oracle and bq.
oracle :
SELECT
to_char(R_PROJECT_S.PROJECT_COPYRIGHT_YEAR),
R_PROJECT_S.PROJECT_TITLE,
to_char(R_PROJECT_S.EDITION),
R_PROJECT_S.CIRCULATION_DESC,
R_PROJECT_S.DISTRIBUTION_DESC,
R_PROJECT_S.PROJECT_ID,
DB.R_USAGE_INFO_S.OBJECT_ID,
UPPER(DB.R_INFO_S.PHOTOGRAPHER),
UPPER(DB.R_INFO_S.SOURCE_CAPTION),
ADMIN.BIC_APHEISBN00_BO_VW.BIC_ZCHEAU,
ADMIN.BIC_APHEISBN00_BO_VW.BIC_ZCHECPYR,
ADMIN.BIC_APHEISBN00_BO_VW.BIC_ZCHEED,
ADMIN.BIC_APHEISBN00_BO_VW.BIC_ZCHEPRDDE,
ADMIN.BIC_APHEISBN00_BO_VW.BIC_ZCHEGRDE,
ADMIN.BIC_APHEISBN00_BO_VW.BIC_ZCHSODE,
R_PROJECT_S.CHARGE_TO_ISBN,
ADMIN.BIC_APHEISBN00_BO_VW.BIC_ZCHEPTIT,
DB.R_INFO_S.SOURCE_NAME,
R_PROJECT_S.LANGUAGE_DESC,
R_PROJECT_S.PROJECT_FORMAT_DESC,
DB.R_USAGE_INFO_S.USAGE_ID,
DB.R_USAGE_INFO_S.PAGE,
DB.R_USAGE_INFO_S.CHAPTER,
DB.R_INFO_S.WORK_PROJECT_ID,
DB.R_INFO_S.IMAGE_TYPE_DESC,
DB.R_INFO_S.IMAGE_DESC,
DB.R_USAGE_INFO_S.PERMISSION_TYPE_DESC,
DB.R_USAGE_INFO_S.PERMISSION_STATUS_DESC,
DB.R_USAGE_INFO_S.PERMISSION_USAGE_DESC,
DB.R_USAGE_INFO_S.USAGE_LABEL,
DB.R_USAGE_INFO_S.QUOTED_COST,
DB.R_INFO_S.SOURCE_OBJECT_ID,
DB.R_USAGE_INFO_S.USAGE_TYPE_DESC,
GHEPM_TITLE_PSPP.TITLE_DESCRIPTION,
ADMIN.BIC_APHEISBN00_BO_VW.BIC_ZCHESOAB,
ADMIN.BIC_APHEISBN00_BO_VW.BIC_ZCHEGRCD
FROM
DB.R_PROJECT_S_VW R_PROJECT_S,
DB.R_USAGE_INFO_S,
DB.R_INFO_S,
ADMIN.BIC_APHEISBN00_BO_VW,
DB.GHEPM_TITLE GHEPM_TITLE_PSPP
WHERE
( R_PROJECT_S.PROJECT_ID=DB.R_USAGE_INFO_S.PROJECT_ID(+)
)
AND ( DB.R_USAGE_INFO_S.OBJECT_ID=DB.R_INFO_S.OBJECT_ID )
AND ( R_PROJECT_S.PROJECT_ID=ADMIN.BIC_APHEISBN00_BO_VW.BIC_ZCHETIIS(+) )
AND ( R_PROJECT_S.PROJECT_ID=DB.GHEPM_TITLE_PSPP.ISBN10(+) )
AND UPPER(DB.R_USAGE_INFO_S.USAGE_LABEL) NOT LIKE UNISTR('%KILL%')
BQ:
SELECT
CAST(R_PROJECT_S.PROJECT_COPYRIGHT_YEAR AS string) COPYRIGHT_YEAR,
R_PROJECT_S.PROJECT_TITLE,
CAST(R_PROJECT_S.EDITION AS string) EDITION,
R_PROJECT_S.CIRCULATION_DESC,
R_PROJECT_S.DISTRIBUTION_DESC,
R_PROJECT_S.PROJECT_ID,
R_USAGE_INFO_S.OBJECT_ID,
UPPER(R_INFO_S.PHOTOGRAPHER) PHOTOGRAPHER,
UPPER(R_INFO_S.SOURCE_CAPTION) SOURCE_CAPTION,
BIC_APHEISBN00_BO._BIC_ZCHEAU,
BIC_APHEISBN00_BO._BIC_ZCHECPYR,
BIC_APHEISBN00_BO._BIC_ZCHEED,
BIC_APHEISBN00_BO._BIC_ZCHEPRDDE,
BIC_APHEISBN00_BO._BIC_ZCHEGRDE,
BIC_APHEISBN00_BO._BIC_ZCHSODE,
R_PROJECT_S.CHARGE_TO_ISBN,
BIC_APHEISBN00_BO._BIC_ZCHEPTIT,
R_INFO_S.SOURCE_NAME,
R_PROJECT_S.LANGUAGE_DESC,
R_PROJECT_S.PROJECT_FORMAT_DESC,
R_USAGE_INFO_S.USAGE_ID,
R_USAGE_INFO_S.PAGE,
R_USAGE_INFO_S.CHAPTER,
R_INFO_S.WORK_PROJECT_ID,
R_INFO_S.IMAGE_TYPE_DESC,
R_INFO_S.IMAGE_DESC,
R_USAGE_INFO_S.PERMISSION_TYPE_DESC,
R_USAGE_INFO_S.PERMISSION_STATUS_DESC,
R_USAGE_INFO_S.PERMISSION_USAGE_DESC,
R_USAGE_INFO_S.USAGE_LABEL,
R_USAGE_INFO_S.QUOTED_COST,
R_INFO_S.SOURCE_OBJECT_ID,
R_USAGE_INFO_S.USAGE_TYPE_DESC,
GHEPM_TITLE_PSPP.TITLE_DESCRIPTION,
BIC_APHEISBN00_BO._BIC_ZCHESOAB,
BIC_APHEISBN00_BO._BIC_ZCHEGRCD
FROM
`domain-rr.oracle_DB_DB.R_info_s` R_INFO_S
inner join
`domain-rr.oracle_DB_DB.R_usage_info_s` R_USAGE_INFO_S
on
R_USAGE_INFO_S.OBJECT_ID=R_INFO_S.OBJECT_ID
right outer join
`domain-rr.DB_RPT.R_PROJECT_S_VW` R_PROJECT_S
on
R_PROJECT_S.PROJECT_ID=R_USAGE_INFO_S.PROJECT_ID
left outer join
`domain-rr.DB_RPT.BIC_APHEISBN00_BO_VW` BIC_APHEISBN00_BO
ON
R_PROJECT_S.PROJECT_ID=BIC_APHEISBN00_BO._BIC_ZCHETIIS
left outer join
`domain-rr.oracle_DB_DB.ghepm_title` GHEPM_TITLE_PSPP
ON
R_PROJECT_S.PROJECT_ID=GHEPM_TITLE_PSPP.ISBN10
AND UPPER(R_USAGE_INFO_S.USAGE_LABEL) NOT LIKE '%KILL%'
Oracle count - 1553437
BQ count - 2414413
Please help me on how to get counts are same on both oracle and bq
Thanks,
Naren
Had you used more readable, shortened table aliases several differences can be illuminated:
Oracle does not attempt any RIGHT JOIN;
GBQ should run UPPER(...) expression in WHERE not on last LEFT JOIN clause or move expression to INNER JOIN on ui table (but without testing may not make a difference but readability);
Table order may make a difference especially with use of both INNER and OUTER joins;
Oracle (using the older, outdated implicit joins)
...
FROM
GRDW.RMS_IMAGE_PROJECT_S_VW p,
GRDW.RMS_IMAGE_USAGE_INFO_S ui,
GRDW.RMS_IMAGE_INFO_S i,
BOADMIN.BIC_APHEISBN00_BO_VW b,
GRDW.GHEPM_TITLE g
WHERE
( p.PROJECT_ID = ui.PROJECT_ID(+) -- LEFT JOIN
)
AND ( ui.OBJECT_ID = i.OBJECT_ID ) -- INNER JOIN
AND ( p.PROJECT_ID = b.BIC_ZCHETIIS(+) ) -- LEFT JOIN
AND ( p.PROJECT_ID = g.ISBN10(+) ) -- LEFT JOIN
AND UPPER(ui.USAGE_LABEL) NOT LIKE UNISTR('%KILL%')
Google BigQuery (using current standard of explicit joins)
...
FROM
`pearson-rr.oracle_grdw_grdw.rms_image_info_s` i
INNER JOIN
`pearson-rr.oracle_grdw_grdw.rms_image_usage_info_s` ui
ON ui.OBJECT_ID = i.OBJECT_ID
RIGHT OUTER JOIN
`pearson-rr.GRDW_RPT.RMS_IMAGE_PROJECT_S_VW` p
ON p.PROJECT_ID = ui.PROJECT_ID
LEFT OUTER JOIN
`pearson-rr.GRDW_RPT.BIC_APHEISBN00_BO_VW` b
ON p.PROJECT_ID = b._BIC_ZCHETIIS
LEFT OUTER JOIN
`pearson-rr.oracle_grdw_grdw.ghepm_title` g
ON p.PROJECT_ID = g.ISBN10
AND UPPER(ui.USAGE_LABEL) NOT LIKE '%KILL%'
Therefore, to account for table order and appropriate JOIN, consider below adjusted Google BigQuery:
...
FROM
`pearson-rr.GRDW_RPT.RMS_IMAGE_PROJECT_S_VW` p
LEFT OUTER JOIN
`pearson-rr.oracle_grdw_grdw.rms_image_usage_info_s` ui
ON p.PROJECT_ID = ui.PROJECT_ID
INNER OUTER JOIN
`pearson-rr.oracle_grdw_grdw.rms_image_info_s` i
ON ui.OBJECT_ID = i.OBJECT_ID AND UPPER(ui.USAGE_LABEL) NOT LIKE '%KILL%'
LEFT OUTER JOIN
`pearson-rr.GRDW_RPT.BIC_APHEISBN00_BO_VW` b
ON p.PROJECT_ID = b._BIC_ZCHETIIS
LEFT OUTER JOIN
`pearson-rr.oracle_grdw_grdw.ghepm_title` g
ON p.PROJECT_ID = g.ISBN10
I'm fairly new to sql and am probably over my head with this but I keep running into a syntax error in my join statement.
I am trying to get specific stats for a single character. I have added more parenthese to get rid of a missing operator error, and I have tried adding parenthese to only around the inner joins of the same tables. So far the join statement is the only thing throwing errors.
SELECT CHARACTER.CharacterName, CHARACTER.Alignment, INVENTORY.Equipped,
ITEMS.ItemName,
ITEMS.PhysDef, ITEMS.MDef, ITEMS.Dodge, ITEMS.Damage, ITEMS.CritMultiplier,
ITEMS.Range,
ITEMS.AttackSpeed, JOB_CHARACTER.JobLevel, RACE_CHARACTER.RacialLevel,
RACE.RaceName, RACE.Strength,
RACE.Skill, RACE.Vitality, RACE.Arcane, RACE.Spirit, RACE.Charisma,
RACE.Luck, JOB.JobName,
JOB.HP, JOB.AttackBonus, JOB.Agility, JOB.Might, JOB.SpellPower, JOB.Vital,
JOB.Nimble, JOB.Mental,
JOB.Curese, JOB.SpellCasting, JOB.ManaBase, JOB.ManaType, JOB.Ki,
SKILLS.Alchemy, SKILLS.Awareness,
SKILLS.Climb, SKILLS.Coach, SKILLS.Construction, SKILLS.Decieve,
SKILLS.DisarmMechanism,
SKILLS.DiscernTruth, SKILLS.Dishearten, SKILLS.Fly, SKILLS.Forge,
SKILLS.Gymnastics,SKILLS.Identify,
SKILLS.Leadership, SKILLS.Lore_9Realms, SKILLS.Lore_Alternative,
SKILLS.Lore_Arcane,
SKILLS.Lore_Arithmancy, SKILLS.Lore_Divine, SKILLS.Lore_Geography,
SKILLS.Lore_Nature,
SKILLS.Lore_Nobility, SKILLS.Lore_Religion, SKILLS.Lore_Spiritual,
SKILLS.Medical,
SKILLS.Performance, SKILLS.Ride, SKILLS.Steal, SKILLS.Stealth,
SKILLS.Subterfuge,
SKILLS.Swim, SKILLS.Tailor, SKILLS.UseContraption, SKILLS.Wilderness
FROM (((((((CHARACTER INNER JOIN RACE_CHARACTER ON
CHARACTER.CharacterID=RACE_CHARACTER.CharacterID)
LEFT JOIN JOB_CHARACTER ON CHARACTER.CharacterID=JOB_CHARACTER.CharacterID)
LEFT JOIN INVENTORY ON CHARACTER.CharacterID=INVENTORY.CharacterID)
INNER JOIN INVENTORY ON ITEMS.ItemID =INVENTORY.ItemID)
INNER JOIN JOB ON JOB.JobID=JOB_CHARACTER.JobID)
LEFT JOIN SKILLS ON JOB.JobID=SKILLS.JobID)
INNER JOIN RACE ON RACE.RaceID=RACE_CHARACTER.RaceID)
WHERE ((CHARACTER.CharacterID)=1) AND ((JOB.JobID)=3) AND
((RACE.RaceID)=6);
I expect this to output the stats for this single character, its name, and skills, however it is not currently outputting anything.
Your select statement is sourcing 8 fields from an ITEMS table:
SELECT
...
ITEMS.ItemName,
ITEMS.PhysDef,
ITEMS.MDef,
ITEMS.Dodge,
ITEMS.Damage,
ITEMS.CritMultiplier,
ITEMS.Range,
ITEMS.AttackSpeed,
...
However, the ITEMS table is not referenced by your from clause:
FROM
(
(
(
(
(
(
(
CHARACTER INNER JOIN RACE_CHARACTER ON
CHARACTER.CharacterID=RACE_CHARACTER.CharacterID
)
LEFT JOIN JOB_CHARACTER ON
CHARACTER.CharacterID=JOB_CHARACTER.CharacterID
)
LEFT JOIN INVENTORY ON
CHARACTER.CharacterID=INVENTORY.CharacterID
)
INNER JOIN INVENTORY ON ----------< INVENTORY table referenced twice
ITEMS.ItemID =INVENTORY.ItemID
)
INNER JOIN JOB ON
JOB.JobID=JOB_CHARACTER.JobID
)
LEFT JOIN SKILLS ON
JOB.JobID=SKILLS.JobID
)
INNER JOIN RACE ON
RACE.RaceID=RACE_CHARACTER.RaceID
)
I should imagine the SQL code should be changed to something like:
SELECT
CHARACTER.CharacterName,
CHARACTER.Alignment,
INVENTORY.Equipped,
ITEMS.ItemName,
ITEMS.PhysDef,
ITEMS.MDef,
ITEMS.Dodge,
ITEMS.Damage,
ITEMS.CritMultiplier,
ITEMS.Range,
ITEMS.AttackSpeed,
JOB_CHARACTER.JobLevel,
RACE_CHARACTER.RacialLevel,
RACE.RaceName,
RACE.Strength,
RACE.Skill,
RACE.Vitality,
RACE.Arcane,
RACE.Spirit,
RACE.Charisma,
RACE.Luck,
JOB.JobName,
JOB.HP,
JOB.AttackBonus,
JOB.Agility,
JOB.Might,
JOB.SpellPower,
JOB.Vital,
JOB.Nimble,
JOB.Mental,
JOB.Curese,
JOB.SpellCasting,
JOB.ManaBase,
JOB.ManaType,
JOB.Ki,
SKILLS.Alchemy,
SKILLS.Awareness,
SKILLS.Climb,
SKILLS.Coach,
SKILLS.Construction,
SKILLS.Decieve,
SKILLS.DisarmMechanism,
SKILLS.DiscernTruth,
SKILLS.Dishearten,
SKILLS.Fly,
SKILLS.Forge,
SKILLS.Gymnastics,
SKILLS.Identify,
SKILLS.Leadership,
SKILLS.Lore_9Realms,
SKILLS.Lore_Alternative,
SKILLS.Lore_Arcane,
SKILLS.Lore_Arithmancy,
SKILLS.Lore_Divine,
SKILLS.Lore_Geography,
SKILLS.Lore_Nature,
SKILLS.Lore_Nobility,
SKILLS.Lore_Religion,
SKILLS.Lore_Spiritual,
SKILLS.Medical,
SKILLS.Performance,
SKILLS.Ride,
SKILLS.Steal,
SKILLS.Stealth,
SKILLS.Subterfuge,
SKILLS.Swim,
SKILLS.Tailor,
SKILLS.UseContraption,
SKILLS.Wilderness
FROM
(
(
(
(
(
(
(
CHARACTER INNER JOIN RACE_CHARACTER ON
CHARACTER.CharacterID=RACE_CHARACTER.CharacterID
)
LEFT JOIN JOB_CHARACTER ON
CHARACTER.CharacterID=JOB_CHARACTER.CharacterID
)
LEFT JOIN INVENTORY ON
CHARACTER.CharacterID=INVENTORY.CharacterID
)
LEFT JOIN ITEMS ON
ITEMS.ItemID =INVENTORY.ItemID
)
LEFT JOIN JOB ON
JOB.JobID=JOB_CHARACTER.JobID
)
LEFT JOIN SKILLS ON
JOB.JobID=SKILLS.JobID
)
INNER JOIN RACE ON
RACE.RaceID=RACE_CHARACTER.RaceID
)
WHERE
CHARACTER.CharacterID = 1 AND
JOB.JobID = 3 AND
RACE.RaceID = 6
Note that I have changed a couple of the inner joins to left joins because if you use an inner join on a table which is the right of a left join (or on the left of a right join), then you will receive an ambiguous outer joins error.
Goal:
I wish to get the Count of how many times a WorkItem was re-assigned
From what I understand the proper query is the following:
SELECT
WorkItemDimvw.Id,
COUNT(WorkItemAssignedToUserFactvw.WorkItemAssignedToUser_UserDimKey) AS Assignments
FROM WorkItemDimvw INNER JOIN WorkItemAssignedToUserFactvw
ON WorkItemDimvw.WorkItemDimKey = WorkItemAssignedToUserFactvw.WorkItemDimKey
GROUP BY WorkItemDimvw.Id
The EXISTING query is below and I'm wondering / forgeting if I should:
Just add in COUNT(WorkItemAssignedToUserFactvw.WorkItemAssignedToUser_UserDimKey) AS Assignments since joins are existing, except it is group by WorkItemDimvw.Id
Should it instead be a subquery in the Select below?
Query:
SELECT
SRD.ID,
SRD.Title,
SRD.Description,
SRD.EntityDimKey,
WI.WorkItemDimKey,
IATUFact.DateKey
FROM
SLAConfigurationDimvw
INNER JOIN SLAInstanceInformationFactvw
ON SLAConfigurationDimvw.SLAConfigurationDimKey = SLAInstanceInformationFactvw.SLAConfigurationDimKey
RIGHT OUTER JOIN ServiceRequestDimvw AS SRD
INNER JOIN WorkItemDimvw AS WI
ON SRD.EntityDimKey = WI.EntityDimKey
LEFT OUTER JOIN WorkItemAssignedToUserFactvw AS IATUFact
ON WI.WorkItemDimKey = IATUFact.WorkItemDimKey
AND IATUFact.DeletedDate IS NULL
The trick is to aggregate the data on a sub query, before you join it.
SELECT
SRD.ID,
SRD.Title,
SRD.Description,
SRD.EntityDimKey,
WI.WorkItemDimKey,
IATUFact.DateKey,
IATUFact.Assignments
FROM
SLAConfigurationDimvw
INNER JOIN
SLAInstanceInformationFactvw
ON SLAConfigurationDimvw.SLAConfigurationDimKey = SLAInstanceInformationFactvw.SLAConfigurationDimKey
RIGHT OUTER JOIN
ServiceRequestDimvw AS SRD
ON <you're missing something here>
INNER JOIN
WorkItemDimvw AS WI
ON SRD.EntityDimKey = WI.EntityDimKey
LEFT OUTER JOIN
(
SELECT
WorkItemDimKey,
DateKey,
COUNT(WorkItemAssignedToUser_UserDimKey) AS Assignments
FROM
WorkItemAssignedToUserFactvw
WHERE
DeletedDate IS NULL
GROUP BY
WorkItemDimKey,
DateKey
)
IATUFact
ON WI.WorkItemDimKey = IATUFact.WorkItemDimKey
I'm attempting the following query,
DECLARE #EntityType varchar(25)
SET #EntityType = 'Accessory';
WITH Entities (
E_ID, E_Type,
P_ID, P_Name, P_DataType, P_Required, P_OnlyOne,
PV_ID, PV_Value, PV_EntityID, PV_ValueEntityID,
PV_UnitValueID, PV_UnitID, PV_UnitName, PV_UnitDesc, PV_MeasureID, PV_MeasureName, PV_UnitValue,
PV_SelectionID, PV_DropDownID, PV_DropDownName, PV_DropDownOptionID, PV_DropDownOptionName, PV_DropDownOptionDesc,
RecursiveLevel
)
AS
(
-- Original Query
SELECT dbo.Entity.ID AS E_ID, dbo.EntityType.Name AS E_Type,
dbo.Property.ID AS P_ID, dbo.Property.Name AS P_Name, DataType.Name AS P_DataType, Required AS P_Required, OnlyOne AS P_OnlyOne,
dbo.PropertyValue.ID AS PV_ID, dbo.PropertyValue.Value AS PV_Value, dbo.PropertyValue.EntityID AS PV_EntityID, dbo.PropertyValue.ValueEntityID AS PV_ValueEntityID,
dbo.UnitValue.ID AS PV_UnitValueID, dbo.UnitOfMeasure.ID AS PV_UnitID, dbo.UnitOfMeasure.Name AS PV_UnitName, dbo.UnitOfMeasure.Description AS PV_UnitDesc, dbo.Measure.ID AS PV_MeasureID, dbo.Measure.Name AS PV_MeasureName, dbo.UnitValue.UnitValue AS PV_UnitValue,
dbo.DropDownSelection.ID AS PV_SelectionID, dbo.DropDown.ID AS PV_DropDownID, dbo.DropDown.Name AS PV_DropDownName, dbo.DropDownOption.ID AS PV_DropDownOptionID, dbo.DropDownOption.Name AS PV_DropDownOptionName, dbo.DropDownOption.Description AS PV_DropDownOptionDesc,
0 AS RecursiveLevel
FROM dbo.Entity
INNER JOIN dbo.EntityType ON dbo.EntityType.ID = dbo.Entity.TypeID
INNER JOIN dbo.Property ON dbo.Property.EntityTypeID = dbo.Entity.TypeID
INNER JOIN dbo.PropertyValue ON dbo.Property.ID = dbo.PropertyValue.PropertyID AND dbo.PropertyValue.EntityID = dbo.Entity.ID
INNER JOIN dbo.DataType ON dbo.DataType.ID = dbo.Property.DataTypeID
LEFT JOIN dbo.UnitValue ON dbo.UnitValue.ID = dbo.PropertyValue.UnitValueID
LEFT JOIN dbo.UnitOfMeasure ON dbo.UnitOfMeasure.ID = dbo.UnitValue.UnitOfMeasureID
LEFT JOIN dbo.Measure ON dbo.Measure.ID = dbo.UnitOfMeasure.MeasureID
LEFT JOIN dbo.DropDownSelection ON dbo.DropDownSelection.ID = dbo.PropertyValue.DropDownSelectedID
LEFT JOIN dbo.DropDownOption ON dbo.DropDownOption.ID = dbo.DropDownSelection.SelectedOptionID
LEFT JOIN dbo.DropDown ON dbo.DropDown.ID = dbo.DropDownSelection.DropDownID
WHERE dbo.EntityType.Name = #EntityType
UNION ALL
-- Recursive Query?
SELECT E2.E_ID AS E_ID, dbo.EntityType.Name AS E_Type,
dbo.Property.ID AS P_ID, dbo.Property.Name AS P_Name, DataType.Name AS P_DataType, Required AS P_Required, OnlyOne AS P_OnlyOne,
dbo.PropertyValue.ID AS PV_ID, dbo.PropertyValue.Value AS PV_Value, dbo.PropertyValue.EntityID AS PV_EntityID, dbo.PropertyValue.ValueEntityID AS PV_ValueEntityID,
dbo.UnitValue.ID AS PV_UnitValueID, dbo.UnitOfMeasure.ID AS PV_UnitID, dbo.UnitOfMeasure.Name AS PV_UnitName, dbo.UnitOfMeasure.Description AS PV_UnitDesc, dbo.Measure.ID AS PV_MeasureID, dbo.Measure.Name AS PV_MeasureName, dbo.UnitValue.UnitValue AS PV_UnitValue,
dbo.DropDownSelection.ID AS PV_SelectionID, dbo.DropDown.ID AS PV_DropDownID, dbo.DropDown.Name AS PV_DropDownName, dbo.DropDownOption.ID AS PV_DropDownOptionID, dbo.DropDownOption.Name AS PV_DropDownOptionName, dbo.DropDownOption.Description AS PV_DropDownOptionDesc,
(RecursiveLevel + 1)
FROM Entities AS E2
INNER JOIN dbo.Entity ON dbo.Entity.ID = E2.PV_ValueEntityID
INNER JOIN dbo.EntityType ON dbo.EntityType.ID = dbo.Entity.TypeID
INNER JOIN dbo.Property ON dbo.Property.EntityTypeID = dbo.Entity.TypeID
INNER JOIN dbo.PropertyValue ON dbo.Property.ID = dbo.PropertyValue.PropertyID AND dbo.PropertyValue.EntityID = E2.E_ID
INNER JOIN dbo.DataType ON dbo.DataType.ID = dbo.Property.DataTypeID
INNER JOIN dbo.UnitValue ON dbo.UnitValue.ID = dbo.PropertyValue.UnitValueID
INNER JOIN dbo.UnitOfMeasure ON dbo.UnitOfMeasure.ID = dbo.UnitValue.UnitOfMeasureID
INNER JOIN dbo.Measure ON dbo.Measure.ID = dbo.UnitOfMeasure.MeasureID
INNER JOIN dbo.DropDownSelection ON dbo.DropDownSelection.ID = dbo.PropertyValue.DropDownSelectedID
INNER JOIN dbo.DropDownOption ON dbo.DropDownOption.ID = dbo.DropDownSelection.SelectedOptionID
INNER JOIN dbo.DropDown ON dbo.DropDown.ID = dbo.DropDownSelection.DropDownID
)
SELECT E_ID, E_Type,
P_ID, P_Name, P_DataType, P_Required, P_OnlyOne,
PV_ID, PV_Value, PV_EntityID, PV_ValueEntityID,
PV_UnitValueID, PV_UnitID, PV_UnitName, PV_UnitDesc, PV_MeasureID, PV_MeasureName, PV_UnitValue,
PV_SelectionID, PV_DropDownID, PV_DropDownName, PV_DropDownOptionID, PV_DropDownOptionName, PV_DropDownOptionDesc,
RecursiveLevel
FROM Entities
INNER JOIN [dbo].[Entity] AS dE
ON dE.ID = PV_EntityID
The problem is the second query, the "recursive one" is getting the data I expect since I can't do the LEFT JOINs like in the first query. (At least to my understanding).
If I remove the fetching of the data that requires the LEFT (Outer) JOINs then the recursion works perfectly. My problem is I need both. Is there a way I can accomplish this?
Per http://msdn.microsoft.com/en-us/library/ms175972.aspx you can not have a left/right/outer join in a recursive CTE.
For a recursive CTE you can't use a subquery either so I sugest following this example.
They use two CTE's. The first is not recursive and does the left join to get the data it needs. The second CTE is recursive and inner joins on the first CTE. Since CTE1 is not recursive it can left join and supply default values for the missing rows and is guarenteed to work in the inner join.
However, you can also duplicate a left join with a union and subselect though it isn't really useful normally but it is interesting.
In that case, you would keep your first statement how it is. It will match all rows that join successfully.
Then UNION that query with another query that removes the join, but has a
NOT EXISTS(SELECT 1 FROM MISSING_ROWS_TABLE WHERE MAIN_TABLE.JOIN_CONDITION = MISSING_ROWS_TABLE.JOIN_CONDITION)
This gets all the rows that failed the previous join condition in query 1. You can replace the colmuns you would get from MISSING_ROWS_TABLE with NULL. I had to do this once using a coding framework that didn't support outer joins. Since recursive CTE's don't allow subqueries you have to use the first solution.