I have a sql query that runs fine but it returns results from 2 different tables that contain a breakdown of contracts and the projects that belong to them.
An example of this is: Contract number 12004 contains Projects 12004C, 12004D, 12004F
is there a way I can get all 12004 to group together under the 12004 banner contract Number?
My query as it stands to get me the current info is:
SELECT PA01201.PACONTNUMBER, PA01201.PAPROJNUMBER, PA01201.PAprojname, PA01100.PAcontname
FROM PA01201 INNER JOIN
PA01100 ON PA01201.PACONTNUMBER = PA01100.PACONTNUMBER
basically i am trying to get all the figures from PAPROJNUMBERS (C,D,F etc) to form one line of a subtotal under PACONTNUMBER
I have tried a 'Group By' but get a Ambiguous column name 'PACONTNUMBER'???
Any help at all much appreciated.
Thanks for the help. Much appreciated. I will keep trying different things.
In response to using aggregates that's not really what I was trying to do.
Basically in my example of projects 12004C, 12004D, 12004F etc I just want them all to wrap up under 12004. so it would look something like this..............
Contract Figures Description:-
12004 25000 SS Bus Station
12005 xxxxx xxxxxxxx
12006 xxxxx xxxxxxxx
12007 xxxxx xxxxxxxx
12008 xxxxx xxxxxxxx
instead of how it looks at the moment:-
Contract Figures Description
12004 6000 SS Bus Station
12004C 8000 SS Bus Station
12004D 1000 SS Bus Station
12004F 10000 SS Bus Station
12005 xxxxx xxxxxx
If you get a warning about an ambiguous name, it's because you mention a column that's in more than one table, and the database doesn't know which table you mean.
That being said, depending on the database engine you have (SQLServer, MySQL, Oracle), some have a "concat" function for aggregation.
If you wanna list a contract with all it's projects you'll have to do it the way you are already doing it. the result will look like this:
contract1 project1
contract1 project2
you can't use aggregates to get
contract1
project1
project2
that being said, your Ambiguous error is because you need to write
GROUP BY PA01201.PACONTNUMBER
and not
GROUP BY PACONTNUMBER
it still going to complain about all the other columns not being in an aggregate function(e.g. MAX, COUNT, AVG, MIN ....)
SELECT min(PA01201.PACONTNUMBER) as minPAContNumber,
sum(cast(PA01201.PAPROJNUMBER as int)) as SUMPaProjNumber,
PA01201.PAprojname
FROM PA01201
INNER JOIN PA01100
ON PA01201.PACONTNUMBER = PA01100.PACONTNUMBER
GROUP BY PA01201.PAprojname
I'm assuming paprojnumber is a numeric field since your example is doing math on it.
you can't add0 PA01100.PACONTNUMBER back in to the select or group by as it will create the seperate rows you're trying to avoid; unless you use wm_Concat or a similar function to aggregrage all the different projects into the same line/column
UPDATE based on expected results and comments:
12004 25000 SS Bus Station
12005 xxxxx xxxxxx
is not achievable because paprojnumber contains data such as 0612AB which can not be treated as a number thus when we try and roll up the data into one row adding the projnumbers together, the DBengine can't add 0612AB to the other results.
OR are these results OK?
12004 |8000, 6000, 1000, 10000 | SS BUS STATION
12005 |9000AB, 6000, 2000, 4000 | SS BUS STATION
Related
I have a table that looks like this:
Sku_Code Channel Rank Category Website Date
123 US 28 Toys www.foo.com 2021-06-07
123 US 13 Games www.lolo.com 2021-06-07
328 CA 12 Toys www.lo.com 2021-05-12
123 US 2 Games www.foo.com 2021-06-05
I would like to pivot this table so all ID information falls in one row...like this:
Sku_Code Channel Category Category_1 Website Website_1 Date
123 US Toys Games www.foo.com www.lolo.com 2021-06-07
328 CA Toys www.lo.com 2021-05-12
123 US Games www.foo.com 2021-06-05
It's a fairly large table so wondering whats the best/fastest way to do this? I know there is a pivot function I could use but do not now how to apply it in this situation.
I'm fairly new to SQL so any help would be appreciated.
It's not clear whether an ID can have an arbitrary number of categories. If so, this is not possible in normal SQL alone. The SQL language has a strict requirement for the number and types of columns to be known at query compile time, before looking at any data.
That doesn't mean what you want to do can't happen at all... just that the solution will be more involved. For example, you may need to do the pivot in your reporting tool or client code. The other alternative is dynamic sql over three steps: First, run a query to determine how many categories you will need. Second, use the information from step one to build a new SQL statement on the fly, probably involving an additional join back to the same table for each category, using the PIVOT keyword, or both. Finally, execute the SQL statement built in step two.
I am trying to work with two tables on BigQuery. From table1 I want to find the accession ID of all records that are "World", and then from each of those accession numbers I want to create a column with every name in a separate row. Unfortunately, when I run this:
Select name
From `table2`
Where acc IN (Select acc
From `table1`
WHERE source = 'World')
Instead of getting something like this:
Acc1
Acc2
Acc3
Jeff
Jeff
Ted
Chris
Ted
Blake
Rob
Jack
Jack
I get something more like this:
row
name
1
Jeff
2
Chris
3
Rob
4
Jack
5
Jeff
6
Jack
7
Ted
8
Blake
Ultimately, I am hoping to download the data and somehow use python or something to take each name and count the number of times it shows up with each other name at a given accession number, and furthermore measure the degree to which each pairing is also found with third names in any given column, i.e. the degree to which they share a cohort. So I need to preserve the groupings which exist with each accession number, but I am struggling to find info on how one might do this.
Could anybody point me in the right direct for this, or otherwise is the way I am going about this wise if that is my end goal?
Thanks!
This is not a direct answer to the question you asked. In general, it is easier to handle multiple rows rather than multiple columns.
So, I would recommend that you put each acc value in a separate row and then list the names as an array:
select t2.acc, array_agg(t2.name order by t2.name) as names
from `table2` t2
where t2.acc in (Select t1.acc
From `table1` t1
where t1.source = 'World'
)
group by t2.acc;
Otherwise, you are going to have a challenge just naming the columns in your result set.
I am currently using Access 2016 and am trying to create a query that is pulling in a different query and a table as its 2 source elements. Below is an example of the structure
table:
entity code
legal AP01
admin AP02
acct AP03
query1:
date total billing
1/1/2019 $10 000000-AP01-abcxyz
1/5/2019 $12 000000-AP01-abcxyz
1/12/2019 $15 000000-AP02-abcxyz
I've tried thinking about how to do a join, but since the billing field is a long text due to the fact that some strings are much larger than 255 characters, that is out of the question. So maybe using IN somehow, and the query would look for the code field value in table within the billing field value in query1, and display the following output
query2:
date total billing entity
1/1/2019 $10 000000-AP01-abcxyz legal
1/5/2019 $12 000000-AP01-abcxyz legal
1/12/2019 $15 000000-AP02-abcxyz admin
Using that output I could group by entity and sum total to show total spend within a department. I dont want to have to extract down to excel, run vlookup and find, then re-import it back in to access. There would be no point if I wanted to just do it all in excel. Can this be done within an access query?
You can use instr():
select q1.*, t1.entity
from q1 join
t1
on instr(q1.billing, t1.code) > 0
You can use like:
select
q.*, t.entity
from query1 as q inner join tablename as t
on q.billing like '*-' & t.code & '-*'
From your expected results I assume that code will always be inside billing in the form: ...-AAAA-....
If this is not the case, remove the dashes and use it like this:
on q.billing like '*' & t.code & '*'
I have 2 tables: Customers and Actions, where each customer has uniqe ID (which can be found in each table).
Part of the customers became club members at a specific date (change between the customers). I'm trying to summarize their purchases until that date, and to get those who purchase more than (for example) 200 until they become club members.
For example, I can have the following customer:
custID purchDate purchAmount
1 2015-05-12 100
1 2015-07-12 150
1 2015-12-29 320
Now, assume that custID=1 became a club member at 2015-12-25; in that case, I'd like to get SUM(purchAmount)=250 (pay attention that I'd like to get this customer because 250>200).
I tried the following:
SELECT cust.custID, SUM(purchAmount)totAmount
FROM customers cust
JOIN actions act
ON cust.custID=act.custID
WHERE act.clubMember=1
AND cust.purchDate<act.clubMemberDate
GROUP BY cust.custID
HAVING totAmount>200;
Is it the right way to "attack" this question, or should I use something like while loop over the clubMemberDate (which telling the truth-I don't know how to do)?
I'm working with Teradata.
Your help will be appreciated.
This query is supposed to run with ms access 2003 using SQL. the function JOIN is NOT supported explicitly. implicitly in the WHERE clause is fine...implicity anywhere is fine as long as the word JOIN INNER JOIN Etc is not used.
DayNumnber PastTime
.
.
.
333 Homework
333 TV
334 Date
620 Chores
620 Date
620 Homework
725 Chores
725 Date
888 Internet
888 TV
.
.
.
Hey I would like a query that can Show the most important past time done for each day (TV and internet do not count!) .So importance would be Homework > Chores > Date.So:
DayNumber PastTime
333 Homework
334 Date
620 Homework
725 Chores
Something that might change this problem. Altho all the different past times are listen in a table together. but that was because i appended the table. originally the homework entries. chore entries and date entriess . internet entriess. tv entries. came from different tables.
eg homework 333
homework 620
Is it easier to do it without appending these tables first? I would hopefully like it to be done with the appended table but ya
I was thinking of a mixture of insert. delete... but the hardest part is checking that there is something there for a date a few things and how to put the more important thing done that day . Thank you
Create another table with:
Pri | PastTime
--------------
1 | Homework
2 | Chores
3 | Date
This is a priority list for the items.
Next do:
SELECT MIN(Pri), DayNumber
FROM PastTime_table, Priority_table
WHERE PastTime_table.PastTime = Priority_table.PastTime
GROUP BY DayNumber
This will give you the most important past time for each day. And because TV and Internet are not listed they will not show up.
But it will give you a number, and not the name.
If you had a better SQL you could then join this back to the Priority_table and lookup the name. But I guess you will have to do that part manually.
If you are willing to change the name and call them:
A_Homework
B_Chores
C_Date
instead then you could do (without any extra table):
SELECT MIN(PastTime), DayNumber
FROM PastTime_table
GROUP BY DayNumber
Since it sorts the name alphabetically it will always give you the best one.
You can add a WHERE to remove TV and Internet.