So as the title implies, I have the same exact structure for two queries but I just need to change the grouping. I know I can do a union, however, to narrow the script, is there a way to associate both grouping in one query? For example:
SELECT shtuff FROM report_tickets WHERE something = something GROUP BY companies
//Query two
SELECT shtuff FROM report_tickets WHERE something = something GROUP BY ticket_id
Can I do?:
SELECT * FROM report_tickets WHERE something = something GROUP BY companies AND ticket_id
I know this doesn't work but in concept. Have the query take in account both groupings? ^^
I would need to add the following to line 30 from the linked code below, this may determine if it can work or not.
SUM(IF(ROUND((SELECT difference)) < 1, 1, 0)) AS zero_to_one,
SUM(IF(ROUND((SELECT difference)) BETWEEN 1 AND 8, 1, 0)) AS one_to_eight,
SUM(IF(ROUND((SELECT difference)) BETWEEN 8 AND 24, 1, 0)) AS eight_to_twentyfour,
SUM(IF(ROUND((SELECT difference)) > 24, 1, 0)) AS over_twentyfour,
Related
I'm trying to pull values for the most recent date (COMPUTE_DAY) in a very large dataset - this seems to be a frequently asked question, with the most common solution to be using a subquery on the same table. Unfortunately, my query is timing out every time I try that. The table is partitioned on two columns, REGION and COMPUTE_DAY, with primary keys REGION, COMPUTE_DAY and PLAN_UUID. Are there any ways I can make this query more efficient?
SELECT /*+ use_hash(ipp,ipp2) */
ipp.COMPUTE_DAY,
ipp.ITEM,
ipp.MANUFACTURER,
ipp.ORDER_DATE,
ipp.CARTON,
sum(ipp.TARGET_INVENTORY) as 1,
sum(ipp.CURRENT_INVENTORY) as 2,
sum(ipp.DEMAND) as 3,
sum(ipp.ORDERS) as 4,
sum(ipp.SHIPMENTS) as 5,
sum(ipp.QUANTITY) as 6,
FROM
table ipp
WHERE
ipp.REGION = 1
AND ipp.COMPUTE_DAY = (select max(ipp2.COMPUTE_DAY) from O_IP_PLANS ipp2 where ipp2.REGION_ID = 1 AND ipp2.COMPUTE_DAY BETWEEN TO_DATE('{RUN_DATE_YYYY/MM/DD}','YYYY/MM/DD')-7 AND TO_DATE('{RUN_DATE_YYYY/MM/DD}','YYYY/MM/DD') AND ipp2.PLAN_UUID = ipp.PLAN_UUID)
AND ipp.GROUP_ID = 121
AND ipp.IOG = 1
AND ipp.INTENT = 'YES'
GROUP BY ipp.COMPUTE_DAY,
ipp.ITEM,
ipp.MANUFACTURER,
ipp.ORDER_DATE,
ipp.CARTON;
I wanted to get clarity on how the HAVING component in an SQL statement works, particularly with a SQL statement that has multiple joins. Consider the following SQL select statement:
SELECT
p.id,
p.first_name as [First Name],
p.last_name as [Last Name]
FROM
( [tbl_person] as p
INNER JOIN [tbl_person_languages] as pl
ON [p].[id] = [pl].[person_id])
INNER JOIN [tbl_person_crossCuttingSkills] As ccp
ON [p].[id] = [ccp].[person_id]
WHERE
cint(pl.language_id) in (12,14) AND
cint(ccp.skill_id) in (55)
GROUP BY
p.id,
p.first_name,
p.last_name
HAVING
count(pl.language_id) =2 AND
count(ccp.skill_id) = 1
I want to pull out records, from tbl_person, where a record has all of the WHERE requirements. For example: I want to select all users where they speak a languages Italian (with ID 12) and Spanish (ID 15) AND have a skill of cooking (55). They need to have all requirements, not just one or more. I was under the assumption this is where you would use GROUP BY and HAVING. With the HAVING:
count(pl.language_id) =2
I use count = 2 because there are two options in the language WHERE clause (12 and 14)
And I use
count(ccp.skill_id) = 1
Because there is one value in the WHERE clause (55).
Is this the correct way to be doing this? For some reason, this returns no records (I have one record in my DB of a person who fits these requirements exactly). But, if I change my HAVING to:
count(pl.language_id) =2 AND
count(ccp.skill_id) = 2
It works fine. Why is this? Are my assumptions of how this works incorrect or is there something else going on?
Remember what count() does . . . it counts non-NULL values. So, you are counting two non-NULL values then the counts are the same.
In most dialects of SQL, you can fix this by doing:
HAVING count(distinct pl.language_id) = 2 AND count(distinct ccp.skill_id) = 1
But that doesn't work in MS Access, because MS Access does not support COUNT(DISTINCT).
So, you can be more verbose. In your case:
HAVING SUM(iif(cint(pl.language_id) = 12, 1, 0)) > 0 AND
SUM(iif(cint(pl.language_id) = 14, 1, 0)) > 0 AND
SUM(iif(cint(ccp.skill_id) = 55, 1, 0)) > 0
I'm sorry this HAVING clause is not simpler. You could switch to another database (such as SQL Server Express) that more closely aligns with ANSI functionality.
I am trying to extract data in a tabular format with different values for part-time and full-time, to get an output like this:
but my query generates this error:
syntax error missing operator
What operator is missing from this query?
SELECT
BANINST1_SZVIRST.SZVIRST_TERM_DESC,
Count(BANINST1_SZVIRST.SZVIRST_FULL_PART_IND="F") AS ["Full-time Undergraduate Enrollment"],
Count(IIf(BANINST1_SZVIRST.SZVIRST_FULL_PART_IND="P",1,Null)) AS ["Part-time Undergraduate Enrollment"]
FROM BANINST1_SZVIRST
GROUP BY
BANINST1_SZVIRST.SZVIRST_TERM_DESC,
BANINST1_SZVIRST.SZVIRST_TERM_CODE,
BANINST1_SZVIRST.SZVIRST_LEVL_CODE,
BANINST1_SZVIRST.SZVIRST_FULL_PART_IND
HAVING
(((BANINST1_SZVIRST.SZVIRST_TERM_CODE) In ("201020","201120","201220","201320","201420","201520","201620"))
AND ((BANINST1_SZVIRST.SZVIRST_LEVL_CODE)="01"));
I think you have 4 different conditions happening here that you are testing for:
Counts of people that are Full-Time
Counts of people that are Part-Time
Counts of people that are Graduate
Counts of people that are UnderGraduate
You are on the right track to use the iif() statement. I think that was from a previous question you asked a day or two ago. The iif() statements would be:
SUM(IIF(BANINST1_SZVIRST.SZVIRST_FULL_PART_IND="F", 1, 0)) as [FullTime],
SUM(IIF(BANINST1_SZVIRST.SZVIRST_FULL_PART_IND="P", 1, 0)) as [PartTime],
SUM(IIF(SZVIRST_LEVL_CODE="01", 1, 0)) as [Graduate],
SUM(IIF(SZVIRST_LEVL_CODE="02", 1, 0)) as [UnderGraduate],
I changed the COUNT() to a SUM() just because it feels more natural since the IIF() is returning a 1 or a 0. You could change that back to a COUNT(Iif(<condition>, 1, null)) and it would fine too.
Checking for two conditions
If you want to combine a couple of conditions to get a count, the formula changes slightly.
For insstance, if you wanted a count of all Full-Time People that are also Under Graduates you could use:
SUM(IIF(BANINST1_SZVIRST.SZVIRST_FULL_PART_IND="F" AND SZVIRST_LEVL_CODE="02", 1, 0)) AS [FullTimeUnderGraduates]
Here we put BOTH conditions INSIDE the first parameters of the IIF() formula. If both are TRUE, it returns a 1, then all those 1s gets summed up.
Lastly, if you are wanting to count/sum both Graduate and Under Graduates in your query, then you can't exclude them in your HAVING clause. So you'll need to remove the bit that reads:
((BANINST1_SZVIRST.SZVIRST_LEVL_CODE)="01")
Otherwise a test like
iif(BANINST1_SZVIRST.SZVIRST_LEVL_CODE="01", 1, 0)
will ALWAYS return a 1 and
iif(BANINST1_SZVIRST.SZVIRST_LEVL_CODE="02", 1, 0)
will ALWAYS return 0
Example
The following should run in your database and give you a good working example of the logic discussed above:
SELECT
BANINST1_SZVIRST.SZVIRST_TERM_DESC,
SUM(IIF(BANINST1_SZVIRST.SZVIRST_FULL_PART_IND="F", 1, 0)) as [FullTime],
SUM(IIF(BANINST1_SZVIRST.SZVIRST_FULL_PART_IND="P", 1, 0)) as [PartTime],
SUM(IIF(SZVIRST_LEVL_CODE="01", 1, 0)) as [Graduate],
SUM(IIF(SZVIRST_LEVL_CODE="02", 1, 0)) as [UnderGraduate],
SUM(IIF(BANINST1_SZVIRST.SZVIRST_FULL_PART_IND="F" AND SZVIRST_LEVL_CODE="02", 1, 0)) AS [FullTimeUnderGraduates],
SUM(IIF(BANINST1_SZVIRST.SZVIRST_FULL_PART_IND="P" AND SZVIRST_LEVL_CODE="02", 1, 0)) AS [PartTimeUnderGraduates],
SUM(IIF(BANINST1_SZVIRST.SZVIRST_FULL_PART_IND="F" AND SZVIRST_LEVL_CODE="01", 1, 0)) AS [FullTimeGraduates],
SUM(IIF(BANINST1_SZVIRST.SZVIRST_FULL_PART_IND="P" AND SZVIRST_LEVL_CODE="01", 1, 0)) AS [PartTimeGraduates]
FROM BANINST1_SZVIRST
GROUP BY
BANINST1_SZVIRST.SZVIRST_TERM_DESC,
BANINST1_SZVIRST.SZVIRST_TERM_CODE,
BANINST1_SZVIRST.SZVIRST_LEVL_CODE,
BANINST1_SZVIRST.SZVIRST_FULL_PART_IND
WHERE BANINST1_SZVIRST.SZVIRST_TERM_CODE IN ("201020","201120","201220","201320","201420","201520","201620")
the data is getting logged in the below format .
name count
'EB4_1F_N_MAIN_IN'
'EB4_1F_N_MOD4_IN'
'EB4_1F_N_MOD5_IN'
'EB4_1F_S_MAIN_IN'
'EB4_2F_N_MAIN_IN'
'EB4_2F_S_MAIN_IN'
'EB4_3F_N_MAIN_IN'
'EB4_3F_S_MAIN_IN'
'EB4_3F_SE_TRN_IN'
'EB4_4F_N_MAIN_IN'
'EB4_4F_S_MAIN_IN'
'EB4_4FSE_TRUN_IN'
'EB4_5F_S_MAIN_IN'
'EB4_GF_N_MAIN_IN'
'EB4_GF_S_MAIN_IN'
'EB5_1F_N_MAIN_IN'
'EB5_1F_S_MAIN_IN'
'EB5_2F_N_MAIN_IN'
'EB5_2F_S_MAIN_IN'
'EB5_2F_SW_DMZ_IN'
'EB5_3F_N_MAIN_IN'
'EB5_3F_S_MAIN_IN'
'EB5_4F_N_MAIN_IN'
'EB5_4F_S_MAIN_IN'
'EB5_5F_N_MAIN_IN'
'EB5_5F_S_MAIN_IN'
'EB5_6F_N_MAIN_IN'
'EB5_6F_S_MAIN_IN'
'EB5_DC_EPX_ST_IN'
'EB5_DC_FM_RM1_IN'
'EB5_DC_FM_RM2_IN'
'EB5_DC_NEPAHU_IN'
'EB5_DC_NWPAHU_IN'
'EB5_DC_SO_NWE_IN'
'EB5_GF_N_MAIN_IN'
'EB6_1F_N_MAIN_IN'
'EB6_1F_S_MAIN_IN'
'EB6_1F_SW_ODC_IN'
'EB6_2F_N_MAIN_IN'
'EB6_2F_S_MAIN_IN'
'EB6_3F_N_MAIN_IN'
'EB6_3F_S_MAIN_IN'
'EB6_4F_N_MAIN_IN'
'EB6_4F_S_MAIN_IN'
'EB6_5F_CISCOMAIN'
'EB6_5F_N_MAIN_IN'
'EB6_5F_S_MAIN_IN'
'EB6_GF_N_MAIN_IN'
'EB6_GF_S_MAIN_IN'
Above is the snapshot of the table . count is not shown .My requirement is to add the count of similar names field like adding all 1F_N and similarly .
can u please tell me how do i do this .
Maybe something like this is what you are looking for? I tested using SQL Server as you didn't specify what DBMS you are using. Also you didn't define how you determine similarity... I'm used the four char substring starting at 6 in this query, but it should be easily adapted to suit your needs.
SELECT a.name,
b.cnt AS Count
FROM table1 a
INNER JOIN (SELECT Substring(name, 6, 4) AS substr,
Count(*) AS cnt
FROM table1
GROUP BY Substring(name, 6, 4)) b
ON Substring(a.name, 6, 4) = b.substr
Sample SQL Fiddle
I have the following table:
I am trying to create an SQL query that returns a table that returns three fields:
Year (ActionDate), Count of Built (actiontype = 12), Count of Lost (actiontype = a few different ones)
Bascially, ActionType is a lookup code. So, I'd get back something like:
YEAR CountofBuilt CountofLost
1905 30 18
1929 12 99
1940 60 1
etc....
I figured this would take two SELECT statements put together with a UNION.
I tried the following below but it only spits back two columns (year and countbuilt). My countLost field doesn't appear
My sql currently (MS Access):
SELECT tblHist.ActionDate, Count(tblHist.ActionDate) as countBuilt
FROM ...
WHERE ((tblHist.ActionType)=12)
GROUP BY tblHist.ActionDate
UNION
SELECT tblHist.ActionDate, Count(tblHist.ActionDate) as countLost
FROM ...
WHERE (((tblHist.ActionType)<>2) AND
((tblHist.ActionType)<>3))
GROUP BY tblHist.ActionDate;
Use:
SELECT h.actiondate,
SUM(IIF(h.actiontype = 12, 1, 0)) AS numBuilt,
SUM(IIF(h.actiontype NOT IN (2,3), 1, 0)) AS numLost
FROM tblHist h
GROUP BY h.actiondate
You should not use UNION for such queries. There are many ways to do what you want, for example
Updated to fit access syntax
SELECT tblHist.ActionDate,
COUNT(SWITCH(tblHist.ActionType = 12,1)) as countBuilt,
COUNT(SWITCH(tblHist.ActionType <>1 OR tblHist.ActionType <>2 OR ...,1)) as countLost
FROM ..
WHERE ....
GROUP BY tblHist.ActionDate