MSAccess: Ranking rows based upon column criteria - sql

I have a dataset that looks like this:
Account Cost Centre TransNo
aaa 111 43443
aaa 111 32112
aaa 111 43211
aaa 112 32232
aaa 113 56544
bbb 222 43222
bbb 222 98332
ccc 111 88778
I need a column added that is a counter of the number of rows that relate to that Account/Cost Centre combination:
Account Cost Centre TransNo rCounter
aaa 111 43443 1
aaa 111 32112 2
aaa 111 43211 3
aaa 112 32232 1
aaa 112 56544 2
bbb 222 43222 1
bbb 222 98332 2
ccc 111 88778 1
Is this possible to do in MSAccess using SQL? and how would I go about it (ie what would be the SQL script I would need to write)?
Thanks in advance.

Something like:
SELECT a.Account, a.[Cost Centre], a.TransNo, (SELECT Count(*)
FROM table4 b
WHERE b.Account=a.Account
AND b.[Cost Centre]=a.[Cost Centre]
AND b.TransNo<=a.TransNo) AS AccountNo
FROM Table4 AS a
ORDER BY a.Account, a.[Cost Centre], a.TransNo;

Related

How find duplicates of the same id but different date with SQL (Oracle)

I've got a datatable like that :
id
line
datedt
123
1
01/01/2021
123
2
01/01/2021
123
3
01/01/2021
777
1
13/04/2020
777
2
13/04/2020
123
1
12/04/2021
123
2
12/04/2021
888
1
01/07/2020
888
2
01/07/2020
452
1
05/01/2020
888
1
02/05/2021
888
2
02/05/2021
I'd like to obtain a result like that, ie : the nb of same id with differents dates.
Example we can find 123 with 2 diffents dates, 888 too, but only date for 777 and 452
id
nb
123
2
777
1
888
2
452
1
How could I get that ?
Hope it's clear :)
Thanks you
select id , count(distinct datedt) as nb
from table
group by id

SQL Server 2008 - Fill Same Value Based On The Name

I am working on a query and having a difficult time to figure out how to fill the same value based on one column. Let me explain what I am trying to accomplish....
Says, I have a table like this below with too columns: Name & Value. So, "Select Name, Value FROM Table1 Order By Name" will produce the following result.
Table1
Name Value
AAA 111
AAA
BBB 222
BBB
BBB
BBB
CCC 333
CCC
DDD 444
DDD
DDD
Now, What I am trying to accomplish is producing the result below with the "Select .... from Table1" query.
Table1
Name Value
AAA 111
AAA 111
BBB 222
BBB 222
BBB 222
BBB 222
CCC 333
CCC 333
DDD 444
DDD 444
DDD 444
Please help and provide the sample code if possible.
Thanks in advance
You can use MAX() as a window function:
SELECT Name, Value,
MAX(Value) OVER (PARTITION BY Name) as imputed_name
FROM Table1
ORDER BY Name;

Find all parent and child with a relationship table

I have inherited two tables:
Table 1: Loc
LocID Field1 Field2
---------------------------
1 AAA BBB
2 CCC DDD
3 EEE FFF
4 GGG HHH
5 III JJJ
6 KKK LLL
7 MMM NNN
8 OOO PPP
9 QQQ RRR
10 SSS TTT
11 UUU VVV
Table 2: LocRel
LocID_A LocID_B
-----------------------
1 2
1 3
2 4
2 5
3 6
3 7
5 11
8 9
8 10
So, the LocRel table basically is used to specified the relationships between the various records in the Loc table.
I am struggling with writing a sql statement that will list all the relationships like so:
LocID Level LocIDH_Ancestry Field1 Field2
---------------------------------------------------
1 1 NULL AAA BBB
2 2 1 CCC DDD
3 2 1 EEE FFF
4 3 1,2 GGG HHH
5 3 1,2 III JJJ
6 3 1,3 KKK LLL
7 3 1,3 MMM NNN
8 1 NULL OOO PPP
9 2 8 QQQ RRR
10 2 8 SSS TTT
11 4 1,2,5 UUU VVV
I am not good at all in queries involving relationships, and would really appreciate some help on how the above can be achieved.
Thank you to all!
This answer may be SQL Server specific. I'm not an expert in SQL, so I don't know how much of this is standard and/or adopted in other dbms.
You can implement the kind of queries you mentioned, using recursive queries. Here is a intro to the subject that provides a good starting point.
For your specific query, something like this should do the work.
WITH MyCTE AS
(
SELECT
LocID, 1 as Level,
NULL as LocIDH_Ancestry,
Field1, Field2
FROM
Table1
WHERE
LocID NOT IN (SELECT LocID_B FROM Table2)
UNION ALL
SELECT
t1.LocID,
c.Level + 1 as Level,
t2.LocID_A as LocIDH_Ancestry,
t1.Field1, t1.Field2
FROM
Table1 t1
INNER JOIN
Table2 t2 ON t1.LocID = t2.LocID_A
INNER JOIN
MyCTE c ON t2.LocID_B = c.LocID
)
SELECT *
FROM MyCTE
Hope that helps.

DB2:how to get top

I have a table having data like
pin id name
3 33 jjj
2 22 bbb
1 111 aaaa
1 112 aa
1 113 aaa
4 44 kkk
I want to print rows of the table where if count(*) group by pin =1 (i.e single entry in table ) print the row
if count(*) group by pin >2 then print first two rows
so my out put should be
pin id name
3 33 jjj
2 22 bbb
1 111 aaaa
1 112 aa
4 44 kkk
Use row_number() OVER(partion by pin order by id) as rownum function . Where rownum <3
. As #Clockwork-Muse said, you need to define an order becase you need to say what do you want to see if there are more than 2 rows for a particular pin.
This will generate you desired output.

Select max date No result I want

SELECT
mat.matid,
MAX (to_date(to_char (matdatetable.matdateupdate,'yyyy-mm-dd'),'yyyy-mm-dd')),
mat.matuserid,
mat.matname,
mat.matprice
FROM
matdatetable
LEFT JOIN mat ON matdatetable.sourceid = mat.matid
RESULT
matid matdate update matuserid matname matprice
-------------------------------------------------------------
1 2012-01-01 0:0:0:0 0111-1 aaa 100
1 2012-08-01 0:0:0:0 0111-1 aaa 125
1 2013-08-30 0:0:0:0 0111-1 aaa 150
2 2012-01-01 0:0:0:0 0222-1 bbb 130
2 2012-08-21 0:0:0:0 0222-1 bbb 110
2 2013-07-30 0:0:0:0 0222-1 bbb 100
3 2012-01-01 0:0:0:0 0565-1 ccc 100
3 2013-09-30 0:0:0:0 0565-1 ccc 230
But I want to. Results
matid matdate update matuserid matname matprice
------------------------------------------------------------------
1 2013-08-30 0:0:0:0 0111-1 aaa 150
2 2013-07-30 0:0:0:0 0222-1 bbb 100
3 2013-09-30 0:0:0:0 0565-1 ccc 230
SELECT DISTINCT ON (1)
t.sourceid AS matid
,t.matdateupdate::date AS matdate_update
,m.matuserid
,m.matname
,m.matprice
FROM matdatetable t
LEFT JOIN mat m ON m.matid = t.sourceid
ORDER BY 1, t.matdateupdate DESC;
Gives you the latest (according to matdateupdate) entry per sourceid. Your question isn't clear what you want exactly.
Using sourceid rather than matid, since you have a LEFT JOIN and matid could be NULL. Or your use of LEFT JOIN is incorrect ...
Explanation for DISTINCT ON in this related answer:
Select first row in each GROUP BY group?
t.matdateupdate::date casts your timestamp (assuming for lack of information) to date. That seems to be what you want. If you really need the redundant time 00:00, use datetrunc('day', t.matdateupdate) instead.