Name ExactDate Presents Location
bob1 2011 1 home
bob2 2008 2 school
bob2 2012 3 school
mary2 1986 4 school
mary1 2001 5 home
mary1 2012 6 home
kate1 2011 7 home
kate1 2012 8 home
kate2 2011 9 school
celia2 2011 10 school
celia2 1986 11 school
celia1 1972 12 home
celia1 2012 14 home
celia2 2012 13 school
This problem is done in SQL in MS Access 2003 for a query.
So the goal is we subtract the amount of presents kate got from celia on the same year ( but since there are a few different present values for the same year we choose to have priority of home > school....for example celia and kate both receive presents in 2012 but celia gets both home presents and school presents in 2012 in which case we choose her home present value to do the calculation) and out put should be something like the following:
Name ExactDate PresentsDiff
celiaminuskate 2011 3
celiaminuskate 2012 6
So far I have :
SELECT 'celiaminuskate'AS [NAME],T1.[date] AS [EXACT DATE],
T1.presents T2.presents AS [PRESENTS DIFF]
FROM Some_Table T1, Some_Table T2
part that I think needs to be fixed??
WHERE (T1.Name = 'celia1'>'celia2')
AND (T2.Name = 'kate1'>'kate2')
AND T2.ExactDate = T1.ExactDate
to indicate priority? I'm not too sure how to do it
ORDER BY T1.ExactDate
I created this query and saved it as qryCeliaAndKateGiftDates. It just returns the distinct ExactDate values for which celia and kate both had gifts recorded.
Notice I re-named your Name field to Recipient, because Name is a reserved word.
SELECT DISTINCT celia.ExactDate
FROM
[SELECT ExactDate
FROM Some_Table
WHERE Recipient Like "celia*"
]. AS celia
INNER JOIN [
SELECT ExactDate
FROM Some_Table
WHERE Recipient Like "kate*"
]. AS kate
ON celia.ExactDate = kate.ExactDate
ORDER BY celia.ExactDate;
Then I used correlated subqueries to return the correct Presents values for celia and kate on each of those ExactDates.
SELECT
raw.recipients AS [NAME],
raw.ExactDate AS [EXACT DATE],
(raw.celia_presents - raw.kate_presents) AS [PRESENTS DIFF]
FROM
[SELECT
'celiaminuskate' AS recipients,
dates.ExactDate,
(SELECT TOP 1 Presents
FROM Some_Table
WHERE
Recipient Like "celia*"
And ExactDate = dates.ExactDate
ORDER BY Location) AS celia_presents,
(SELECT TOP 1 Presents
FROM Some_Table
WHERE
Recipient Like "kate*"
And ExactDate = dates.ExactDate
ORDER BY Location) AS kate_presents
FROM qryCeliaAndKateGiftDates AS dates]. AS raw;
It returns the results you requested when run from Access 2003. However correlated subqueries are notoriously slow, so I'll be interested to see what other answers you get.
Related
I need to create automatic weekly assignments of items to sites for my employees.
The items table items_bank looks like that(of course there will be a lot of items with few more languages) :
**item_id** **item_name** **language**
1 Jorge Garcia English
2 Chrissy Metz English
3 Nina Hagen German
4 Harald Glööckle German
5 Melissa Anderson French
6 Pauley Perrette French
My second table is the sites table :
**site_id** **site_name**
1 DR
2 LI
3 IG
I need to assign every week items to the sites with the following constraints :
For each site assign at least X items of English, Y items of German, and so on...
we want to create diversity - so we would like to avoid repeating the assignments of the 2 weeks before
I think we need to create another table in which we can save there the history of the last 2 weeks' assignments.
right now I managed to create an SQL query that assigns items but I don't know how to take the constraints under consideration this is what I create so far :
WITH numbered_tasks AS (
SELECT t.*, row_number() OVER (ORDER BY rand()) item_number, count(*) OVER () total_items
FROM item_bank t
),
numbered_employees AS (
SELECT e.*,row_number() OVER (ORDER BY rand()) site_number,
count(*) OVER () total_sites
FROM sites_bank e
)
SELECT nt.item_name,
ne.acronym
FROM numbered_tasks nt
INNER JOIN numbered_employees ne
ON ne.site_number-1 = mod(nt.item_number-1, ne.total_sites)
Expected results are for the example which says :
site_id=1 have to get 1 item with the English language
site_id=2 have to get 1 item with the German language
site_id=1 have to get 1 item with the French language
**item_id** **language** **Week_number** **site**
1 English 1 1
4 German 1 2
5 French 1 3
Any help will be appreciated!
I'm writing a query that counts company complaints. The query should count the total number of complaints from a company and also break it down into who called from the company to make the complaint. So an example output would be:
Company Ref Company Name Company Complaints Caller Caller Complaints
11 Argos 10 Steve 8
11 Argos 10 JIM 2
So as you can see the query counts the total number of complaints, then also breaks it down to who complained. So far I have everything perfect apart from the total count. My code is:
SELECT COMPANYREF,
COMPANY,
(SELECT COUNT(COMPANYREF)
FROM XCALLSTABLE) AS CompanyCalls,
CALLER,
COUNT(*)
FROM XCALLSTABLE
JOIN XCUSTOMERTABLE ON (XCALLSTABLE.COMPANYREF = XCUSTOMERTABLE.CUSTREF)
JOIN XTELEPHONETABLE ON (XCUSTOMERTABLE.TELEPHONE = XTELEPHONETABLE.PHONENUMBER)
GROUP BY COMPANYREF,
COMPANY,
CALLER
HAVING COUNT(*) > 0 ;
Some sample output for the current code is:
Company Ref Company Name Company Complaints Caller Caller Complaints
145 Comfiture Traders 500 Alexis Patel 4
The issue here is the total count for the company just counts every row, whereas I'm trying to count the occurances of that company appearing in the column.
Any and all help would be greatly appreciated.
Using sstan's code gave a result of
111 Medusa Shipping 4 Lily Morgan 5
111 Medusa Shipping 4 Ruby Walker 6
Whereas the result should be
111 Medusa Shipping 11 Lily Morgan 5
111 Medusa Shipping 11 Ruby Walker 6
I'm sure there is a cleaner way of doing this, but the following query should work:
SELECT companyref,
company,
CompanyCalls,
caller,
COUNT(*)
FROM (SELECT c.companyref,
company,
COUNT(*) OVER (PARTITION BY c.companyref) AS CompanyCalls,
caller
FROM xcallstable c
JOIN xcustomertable ct
ON ct.custref = c.companyref
JOIN xtelephonetable t
ON t.phonenumber = ct.telephone)
GROUP BY companyref, company, CompanyCalls, caller
HAVING COUNT(*) > 0
Here's the instruction:
Display the two largest capital and their corresponding company names in the DocStatus table.
Here's the table DocStatus:
DocID Company Capital
2001 Teewai.com Inc. 250000.00
2002 Fave Company 250000.00
2003 Goldilocks Bakeshop Corp 500000.00
2004 Collegian Exponent Inc. 100000.00
2005 Uniphil Computer Inc. 250000.00
Question:
What's the correct query for this? Thank you.
(500000 and 250000 are the top two but 3 companies have the same capital of 250000)
If you need only the topmost 2 records then try this:
SELECT TOP 2 *
FROM DocStatus
ORDER BY Capital DESC,Company
It will sort the result in descending order of Capital. And if multiple records have same Capital, it will sort them in the ascending order of Company Name. And finally, selects the top 2 records.
The result will be:
DOCID COMPANY CAPITAL
2003 Goldilocks Bakeshop Corp 500000
2002 Fave Company 250000
See result in SQL Fiddle
OR
If you want the companies which have the 1st and 2nd highest capital, use this:
SELECT TOP(2) WITH TIES * FROM DocStatus
ORDER BY Capital DESC
The beauty of this clause is that it can be used with the WITH TIES clause to retrieve all similar rows to a base result set.
The result will be:
DOCID COMPANY CAPITAL
2003 Goldilocks Bakeshop Corp 500000
2001 Teewai.com Inc. 250000
2002 Fave Company 250000
2005 Uniphil Computer Inc. 250000
Read more here.
try this !
select top(2) with ties * from table order by Capital desc
SEE DEMO
I feel like this should be relatively easy to do in a SSRS report. Using VS 2010. I have a table that comes in from a basic sql query. Just dropping the columns into the a table in visual studio. I want to group the table by company first, which I do via the row group properties. I have a table that looks like this.
Company Contact ContactSub SubCert Year
Bank3 Joey Steven.B A 2010
Bank2 Dave James A 2010
Bank2 Dave Steve B 2010
Bank2 Dave Mark B 2010
Bank2 Dave James A 2011
Bank2 Dave Steve A 2011
Bank2 Dave Mark B 2011
Bank2 Dave James A 2012
Bank2 Dave Steve A 2012
Bank2 Dave Mark A 2012
I now want to combine the Contact Subs and their subcert joined into one row. BUT only using the most recent year. Because some ContactSub may have had their SubCert upgraded to an A from a B.
Company Contact ContactSub SubCert Year
Bank3 Joey Steven.B A 2010
Bank2 Dave James,Steve,Mark A,A,A 2012
I added an additional gorup by property, the "Year" column to the row and used this formula for the ContactSub and SubCert columns in the table:
=Join(LookupSet(Fields!Company.Value,Fields!Company.Value,Fields!SubCert.Value,"DataSet Name"),",")
But this returned me:
Company Contact ContactSub SubCert Year
Bank3 Joey Steven.B A 2010
Bank2 Dave James,Steve,Mark,James A,B,B,A, 2012
Steve,Mark,James, Steve A,B,A,A,
Mark A
How could I clarify my formula to make it say for only the newest year instead of using the values for all years?
Hope this makes sense.
With your data:
And a table grouped on Company:
I use the following expressions:
ContactSub
=Join(LookupSet(Fields!Company.Value & Max(Fields!Year.Value)
, Fields!Company.Value & Fields!Year.Value
, Fields!ContactSub.Value
, "DataSet1"), ",")
SubCert
=Join(LookupSet(Fields!Company.Value & Max(Fields!Year.Value)
, Fields!Company.Value & Fields!Year.Value
, Fields!SubCert.Value
, "DataSet1"), ",")
You can see I'm using Max(Fields!Year.Value) as well as Fields!Company.Value to only match on the highest year in the LookupSet expression.
This gives the required results:
Your problem is that it's working as intended - the LOOKUPSET() function is returning all records from your dataset where the Company matches. You need to either tighten your criteria in your use of the LOOKUPSET() function, or add some custom code to go through the returned array and purge duplicates.
One option for tightening up the lookup might be to add a calculated field to your dataset that concatenates the Company name and the Year together, which, at least looking at your sample data, would provide the slightly more unique key you're looking for.
This is essentially a question about constructing an SQL query. The db is implemented with sqlite3. I am a relatively new user of SQL.
I have two tables and want to join them in an unusual way. The following is an example to explain the problem.
Table 1 (t1):
id year name
-------------------------
297 2010 Charles
298 2011 David
300 2010 Peter
301 2011 Richard
Table 2 (t2)
id year food
---------------------------
296 2009 Bananas
296 2011 Bananas
297 2009 Melon
297 2010 Coffee
297 2012 Cheese
298 2007 Sugar
298 2008 Cereal
298 2012 Chocolate
299 2000 Peas
300 2007 Barley
300 2011 Beans
300 2012 Chickpeas
301 2010 Watermelon
I want to join the tables on id and year. The catch is that (1) id must match exactly, but if there is no exact match in Table 2 for the year in Table 1, then I want to choose the year that is the next (lower) available. A selection of the kind that I want to produce would give the following result
id year matchyr name food
-------------------------------------------------
297 2010 2010 Charles Coffee
298 2011 2008 David Cereal
300 2010 2007 Peter Barley
301 2011 2010 Richard Watermelon
To summarise, id=297 had an exact match for year=2010 given in Table 1, so the corresponding line for id=297, year=2010 is chosen from Table 2. id=298, year=2011 did not have a matching year in Table 2, so the next available year (less than 2011) is chosen. As you can see, I would also like to know what that matched year (whether exactly , or inexactly) actually was.
I would very much appreciate (1) an indication (yes/no answer) of whether this is possible to do in SQL alone, or whether I need to look outside SQL, and (2) a solution, if that is not too onerous.
Sure, you can do this in SQL. What you need for the first step is a query which joins t1 and t2 on id, and gives you the various possible years (EDIT: fixed this sentence, the original one was incorporating the next step into it as well). You can create a view called t3 which gives you this as follows:
CREATE VIEW [t3] AS
SELECT t1.id as id, t2.year as year FROM t1 INNER JOIN t2 ON (t1.id = t2.id AND T2.year <= t1.year)
From here, you'll want to get the maximum year from t3 per id:
CREATE VIEW [t4] AS
SELECT id, MAX(year) FROM t3 GROUP BY id
You should be able to join t4 back onto t1 and t2 to get what you want. Of course, there are ways to shorten this, but it should get you thinking along the right lines. Also, I'm guessing it's just an example, but please don't call your tables t1, t2, etc.