I might be missing something very basic, or there is something very wrong;
I am using Apache Cassandra 3.11.4. Version details are as follows:
Connected to Test Cluster at 127.0.0.1:9042.
[cqlsh 5.0.1 | Cassandra 3.7.0 | CQL spec 3.4.2 | Native protocol v4]
I have the following table and I want to get the count of individual citizen-ship status.
CREATE TABLE population.residents (
residentId bigint,
name varchar,
office varchar,
dob date,
citizen text,
PRIMARY KEY((residentId), dob)
);
CREATE MATERIALIZED VIEW population.residents_citizen AS
SELECT citizen, dob, residentid, name, office
FROM population.residents
WHERE citizen IS NOT NULL AND residentid IS NOT NULL AND dob IS NOT NULL
PRIMARY KEY (citizen, dob, residentid);
The following error is obtained when I try to query:
cqlsh> select citizen, count(residentId) from population.residents_citizen GROUP BY citizen;
SyntaxException: line 1:68 missing EOF at 'GROUP' (...(residentId) from population.residents_citizen [GROUP] BY...)
cqlsh> select citizen, count(residentId) from population.residents_citizen_1
GROUP BY citizen, residentId;
SyntaxException: line 1:70 missing EOF at 'GROUP' (...(residentId) from population.residents_citizen_1 [GROUP] BY...)
cqlsh> select citizen, count(residentId) from population.residents_citizen_1 GROUP BY residentId, citizen;
SyntaxException: line 1:70 missing EOF at 'GROUP' (...(residentId) from population.residents_citizen_1 [GROUP] BY...)
cqlsh> select citizen, count(residentId) from population.residents_citizen_1 GROUP BY citizen, dob, residentId;
SyntaxException: line 1:70 missing EOF at 'GROUP' (...(residentId) from population.residents_citizen_1 [GROUP] BY...)
My Data looks like as below:
cqlsh> select * from population.residents;
residentid | dob | citizen | name | office
------------+------------+---------+-------------------+----------------------------------------
25966 | 2019-01-04 | N | Carl Sykes | Leo Cras Vehicula Limited
921412 | 2018-12-13 | N | Brady Harrison | Nulla In Tincidunt Consulting
521367 | 2019-11-18 | Y | Aaron Norton | Pharetra Sed Hendrerit Associates
843096 | 2020-02-03 | N | Preston Leon | A Felis Limited
460162 | 2019-01-17 | N | Neville Good | Odio Aliquam Company
187360 | 2018-12-09 | Y | Emery Pittman | Arcu Ac Orci Foundation
Some advice is really appreciated!
Related
MySql V 8.0
Question: How to write MySQL select to get Consecutive Day Count where the weight value is lesser than the previous day weight value user wise and break when no longer consecutive or weight value is same or greater than the previous day weight value of the same user.
create table userData (recordDate ,userName varchar(100), weight FLOAT);
insert into userData (recordDate, userName, weight)
values
('2020/8/1','Chris', 78),
('2021/8/2','Chris', 77),
('2021/8/3','Chris', 76),
('2021/8/1','Aamir', 78),
('2021/8/2','Aamir', 77),
('2021/8/1','Alex', 78),
('2021/8/2','Alex', 77),
('2021/8/3','Alex', 76),
('2021/8/5','Chris', 78),
('2021/8/6','Chris', 77),
('2021/8/7','Chris', 76),
('2021/8/8','Chris', 75),
('2021/8/8','Aamir', 78),
('2021/8/8','Alex', 78),
('2021/8/9','John', 78),
('2021/8/1','Ali', 78),
('2021/8/10','Chris', 78);
The expected output is
| userName | streakDays | startingDate | endingDate |
| -------- | ---------- | ------------ | ---------- |
| Alex | 3 | 2021-08-01 | 2021-08-03 |
| Chris | 3 | 2021-08-06 | 2021-08-08 |
| Aamir | 2 | 2021-08-01 | 2021-08-02 |
| Ali | 1 | 2021-08-01 | 2021-08-01 |
| John | 1 | 2021-08-09 | 2021-08-09 |
Any help would be appreciated.
According To Your data inserted in the table , This Select Query Works Fine
select userName as un ,
count((select recordDate WHERE userName = un)) as strekdays,
(select recordDate FROM userdata WHERE userName = un limit 1) as startdate ,
(select recordDate FROM userdata WHERE userName = un order by recordDate DESC limit 1) as enddate
from userdata
group by userName
And It Gives Output Like
userName
streakDays
startingDate
endingDate
Aamir
3
2021-08-01
2021-08-08
Alex
4
2021-08-01
2021-08-08
Ali
1
2021-08-01
2021-08-01
Chris
8
2021-08-01
2021-08-10
John
1
2021-08-09
2021-08-09
Let me know If this Works FOr You or not !
Problem resolved with the following query:
select
streakBreakersRemoved.userName,
streakBreakersRemoved.streakDays,
streakBreakersRemoved.startingDate,
streakBreakersRemoved.endingDate
from
(
select
userName,
count(*) as streakDays,
min(recordDate) as startingDate,
max(recordDate) as endingDate,
row_number() over (partition by userName
order by
count(*) desc) as seqNum
from
(
select
initailRecords.*,
row_number() over (partition by userName
order by
recordDate) as initialSeqNum
from
(
select
userData.*,
lag(weight) over (partition by userName
order by
recordDate) as previousWeight
from
userData
)
initailRecords
where
if(previousWeight is null || previousWeight > weight, 1, 0) = 1
)
recordsWithSeqNum
group by
userName,
to_days(recordDate) - initialSeqNum
)
streakBreakersRemoved
where
seqNum = 1
order by
streakDays desc;
Would appreciate if anyone would like to optimize the above query.
I am using postgresql and applying window function. previously I had to find first gid with same last name , and address(street_address and city) so i simply put last name in partition by clause in window function.
but now I have requirement to find first g_id of which last name is not same. while address is same How can I do it ?
This is what i was doing previously.
SELECT g_id as g_id,
First_value(g_id)
OVER (PARTITION BY lname,street_address , city ,
order by last_date DESC NULLS LAST )as c_id,
street_address as street_address FROM my table;
lets say this is my db
g_id | l_name | street_address | city | last_date
_________________________________________________
x1 | bar | abc road | khi | 11-6-19
x2 | bar | abc road | khi | 12-6-19
x3 | foo | abc road | khi | 19-6-19
x4 | harry | abc road | khi | 17-6-19
x5 | bar | xyz road | khi | 11-6-19
_________________________________________________
In previous scenario :
for if i run for the first row my c_id, it should return 'x2' as it considers these rows:
_________________________________________________
g_id | l_name | street_address | city | last_date
_________________________________________________
x1 | bar | abc road | khi | 11-6-19
x2 | bar | abc road | khi | 12-6-19
_________________________________________________
and return a row with latest last_date.
what i want now to select these rows (rows with same street_address and city but no same l_name):
g_id | l_name | street_address | city | last_date
_________________________________________________
x1 | bar | abc road | khi | 11-6-19
x3 | foo | abc road | khi | 19-6-19
x4 | harry | abc road | khi | 17-6-19
_________________________________________________
and output will be x3.
somehow i want to compare last_name column if it is not equals to the current value of last name and then partition by address field. and if no rows satisfy the condition c_id should be equal to current g_id
Looking at your expected output,it's not clear whether you want earliest or oldest for each group. You may change the ORDER BY accordingly for last_date in this query which uses DISTINCT ON
SELECT DISTINCT ON ( street_address, city, l_name) *
FROM mytable
ORDER BY street_address,
city,
l_name,
last_date --change this to last_date desc if you want latest
DEMO
After discussing the details in this chat:
demo:db<>fiddle
SELECT DISTINCT ON (t1.g_id)
t1.*,
COALESCE(t2.g_id, t1.g_id) AS g_id
FROM
mytable t1
LEFT JOIN mytable t2
ON t1.street_address = t2.street_address AND t1.l_name != t2.l_name
ORDER BY t1.g_id, t2.last_date DESC
here is how I solved it using subquery
creating example table.
CREATE TABLE mytable
("g_id" varchar(2), "l_name" varchar(5), "street_address" varchar(8), "city" varchar(3), "last_date" date)
;
INSERT INTO mytable
("g_id", "l_name", "street_address", "city", "last_date")
VALUES
('x1', 'bar', 'abc road', 'khi', '11-6-19'),
('x2', 'bar', 'abc road', 'khi', '12-6-19'),
('x3', 'foo', 'abc road', 'khi', '19-6-19'),
('x4', 'harry', 'abc road', 'khi', '17-6-19'),
('x5', 'bar', 'xyz road', 'khi', '11-6-19')
;
query to get g_ids
SELECT * ,
(select b.g_id from mytable b where (base.g_id = b.g_id) or (base.l_name <>
b.l_name and base.street_address = b.street_address and base.city = b.city )
order by b.last_date desc limit 1)
from mytable base
I'm working on a problem, involving these two tables.
books
isbn | title | author
------------+-----------------------------------------+------------------
1840918626 | Hogwarts: A History | Bathilda Bagshot
3458400871 | Fantastic Beasts and Where to Find Them | Newt Scamander
9136884926 | Advanced Potion-Making | Libatius Borage
transactions
id | patron_id | isbn | checked_out_date | checked_in_date
----+-----------+------------+------------------+-----------------
1 | 1 | 1840918626 | 2012-05-05 | 2012-05-06
2 | 4 | 9136884926 | 2012-05-05 | 2012-05-06
3 | 2 | 3458400871 | 2012-05-05 | 2012-05-06
4 | 3 | 3458400871 | 2018-04-29 | 2018-05-02
5 | 2 | 9136884926 | 2018-05-03 | NULL
6 | 1 | 3458400871 | 2018-05-03 | 2018-05-05
7 | 5 | 3458400871 | 2018-05-05 | NULL
the query "Make a list of all book titles and denote whether or not a copy of that book is checked out." so pretty much just the first table with a checked out column.
im trying to SELECT DISTINCT on a sub query with the checkout books first, but that doesn't work. I've researched and others say to accomplish this use a GROUP BY clause instead of DISTINCT but the examples they provide are one column queries and when more columns are added it doesn't work.
this is my closest attempt
SELECT DISTINCT ON (title)
title, checked_out
FROM(
SELECT b.title, t.checked_in_date IS NULL AS checked_out
FROM transactions t
natural join books b
ORDER BY checked_out DESC
) t;
or you can join only transactions where books are not checked in:
SELECT b.title, t.isbn IS NOT NULL AS checked_out
, t.checked_out_date
FROM books b
LEFT JOIN transactions t ON t.isbn = b.isbn AND t.checked_in_date IS NULL
ORDER BY checked_out DESC
I adjusted your attempt a little bit. Basically I changed the way your data is joined
SELECT DISTINCT ON (title)
title, checked_out
FROM(
SELECT b.title, t.checked_in_date IS NULL AS checked_out
FROM books b
LEFT OUTER JOIN transactions t USING (isbn)
ORDER BY checked_out DESC
) t;
I have data in a self-join hierarchical table where Continents have many Countries have many Regions have many States have many Cities.
Self-joining table structure:
|-------------------------------------------------------------|
| ID | Name | Type | ParentID | IsTopLevel |
|-------------------------------------------------------------|
| 1 | North America | Continent | NULL | 1 |
| 12 | United States | Country | 1 | 0 |
| 113 | Midwest | Region | 12 | 0 |
| 155 | Kansas | State | 113 | 0 |
| 225 | Topeka | City | 155 | 0 |
| 2 | South America | Continent | NULL | 1 |
| 22 | Argentina | Country | 2 | 0 |
| 223 | Southern | Region | 22 | 0 |
| 255 | La Pampa | State | 223 | 0 |
| 777 | Santa Rosa | City | 255 | 0 |
|-------------------------------------------------------------|
I have been able to successfully use a recursive CTE to get the tree structure and depth of each node. Where I am failing is using a pivot to create a nice list of all bottom locations and their corresponding parents at each level.
The expected results:
|------------------------------------------------------------------------------------|
| Continent | Country | Region | State | City | Bottom_Level_ID |
|------------------------------------------------------------------------------------|
| North America | United States | Midwest | Kansas | Topeka | 234 |
| South America | Argentina | Southern | La Pampa | Santa Rosa | 777 |
|------------------------------------------------------------------------------------|
There are a few key points I should clarify.
Every single entry has a bottom level and a top level. There are no
cases where all five Types are not present for a given location.
If I filled out this data, I'd have 50 entries for North America at the
State level, so you can imagine how immense this table is at the
City level for every continent on the planet. Billions of rows.
The reason this is a necessity is because I need to be able to join onto a historical table of all addresses a person has lived at, and journey up the tree. I figure if I have the LocationID from that table, I can just LEFT JOIN onto a View of this query and nab the appropriate columns.
This is an old database, 2005, and I don't have sysadmin or control of the schema.
My CTE Code
--CTE
;WITH Tree
AS (
SELECT ID, Name, ParentID, Type, 1 as Depth
FROM LocationTable
WHERE IsTopLevel = 1
UNION ALL
SELECT L.ID, L.Name, L.ParentID, L.Type, T.Depth+1
FROM Tree T
JOIN LocationTable L
ON L.ParentGUID = T.GUID
)
Good solid data, in a mostly useful format. BUT then I got to thinking about it and isn't the table structure already in this format, so why would I bother doing a depth tree search if I wasn't going to join the entries together at the same time?
Anyway, here was the rest.
The Pivot Attempt
;WITH Tree
AS (
SELECT ID, Name, ParentID, Type
FROM LocationTable
WHERE IsTopLevel = 1
UNION ALL
SELECT L.ID, L.Name, L.ParentID, L.Type
FROM Tree T
JOIN LocationTable L
ON L.ParentGUID = T.GUID
)
select *
from Tree
pivot (
max(Name)
for Type in ([Continent],[Country],[Region],[State],[City])
) pvt
And now I have everything by Type in a column, with nulls for everything else. As I have struggled with before, I need to filter/join the CTE data before I attempt my pivot, but I have no idea where to start with that piece. Everything I have tried is soooooooooo sloooooooow.
Everytime I think I understand CTEs and Pivot, something new makes me extremely humbled. Please help me. ; ;
If your structure is as clean as you describe it (no gaps, 5 levels always) you might go the easy way:
This data really demands for a classical 1:n-table-tree, where your Countries, States etc. live in their own tables and link to their parent record
Make sure there's an index on ParentID and ID!
DECLARE #tbl TABLE(ID INT,Name VARCHAR(100),Type VARCHAR(100),ParentID INT,IsTopLevel BIT);
INSERT INTO #tbl VALUES
(1,'North America','Continent',NULL,1)
,(12,'United States','Country',1,0)
,(113,'Midwest','Region',12,0)
,(155,'Kansas','State',113,0)
,(225,'Topeka','City',155,0)
,(2,'South America','Continent',NULL,1)
,(22,'Argentina','Country',2,0)
,(223,'Southern','Region',22,0)
,(255,'La Pampa','State',223,0)
,(777,'Santa Rosa','City',255,0);
SELECT Level1.Name AS Continent
,Level2.Name AS Country
,Level3.Name AS Region
,Level4.Name AS State
,Level5.Name AS City
,Level5.ID AS Bottom_Level_ID
FROM #tbl AS Level1
INNER JOIN #tbl AS Level2 ON Level1.ID=Level2.ParentID
INNER JOIN #tbl AS Level3 ON Level2.ID=Level3.ParentID
INNER JOIN #tbl AS Level4 ON Level3.ID=Level4.ParentID
INNER JOIN #tbl AS Level5 ON Level4.ID=Level5.ParentID
WHERE Level1.ParentID IS NULL
The result
Continent Country Region State City Bottom_Level_ID
North America United States Midwest Kansas Topeka 225
South America Argentina Southern La Pampa Santa Rosa 777
Another solution with CTE could be :
;WITH Tree
AS (
SELECT cast(NULL as varchar(100)) as C1, cast(NULL as varchar(100)) as C2, cast(NULL as varchar(100)) as C3, cast(NULL as varchar(100)) as C4, Name as C5, ID as B_Level
FROM LocationTable
WHERE IsTopLevel = 1
UNION ALL
SELECT T.C2, T.C3, T.C4, T.C5, L.Name, L.ID
FROM Tree T
JOIN LocationTable L
ON L.ParentID = T.B_Level
)
select *
from Tree
where C1 is not null
ALTER TABLE users ADD todo map;
UPDATE users SET todo = { '1':'1111', '2':'2222', '3':'3' ,.... } WHERE user_id = 'frodo';
now ,i want to run the follow cql ,but failed ,is here any other method ?
SELECT user_id, todo['1'] FROM users WHERE user_id = 'frodo';
ps:
the length my map can change. for example : { '1':'1111', '2':'2222', '3':'3' } or { '1':'1111', '2':'2222', '3':'3', '4':'4444'} or { '1':'1111', '2':'2222', '3':'3', '4':'4444' ...}
If you want to use a map collection, you'll have the limitation that you can only select the collection as a whole (docs).
I think you could use the suggestion from the referenced question, even if the length of your map changes. If you store those key/value pairs for each user_id in separate fields, and make your primary key based on user_id and todo_k, you'll have access to them in the select query.
For example:
CREATE TABLE users (
user_id text,
todo_k text,
todo_v text,
PRIMARY KEY (user_id, todo_k)
);
-----------------------------
| user_id | todo_k | todo_v |
-----------------------------
| frodo | 1 | 1111 |
| frodo | 2 | 2222 |
| sam | 1 | 11 |
| sam | 2 | 22 |
| sam | 3 | 33 |
-----------------------------
Then you can do queries like:
select user_id,todo_k,todo_v from users where user_id = 'frodo';
select user_id,todo_k,todo_v from users where user_id = 'sam' and todo_k = 2;