SQL - HELP - Write a query to get the Full name, email id, phone of tenants who are married and paying rent > 9000 using subqueries - subquery

I have two tables from which the queries to be executed below is the query which have written, need help in joining the link between the query
select FIRST_NAME+ ' '+ LAST_NAME as FULL_NAME,PHONE,EMAIL
FROM PROFILES
WHERE PROFILE_ID IN
((
SELECT PROFILE_ID
FROM PROFILES
WHERE MARITIAL_STATUS= 'Y' ) and
( SELECT PROFILE_ID
FROM TENANCY_HISTORIES
WHERE RENT> '9000'));

You are using and in the list of ID's output for the in clause. Try as following:
select FIRST_NAME+ ' '+ LAST_NAME as FULL_NAME,PHONE,EMAIL
FROM PROFILES
WHERE
(PROFILE_ID IN
(
SELECT PROFILE_ID
FROM PROFILES
WHERE MARITIAL_STATUS= 'Y' ) or PROFILE_ID IN
( SELECT PROFILE_ID
FROM TENANCY_HISTORIES
WHERE RENT> '9000'));

Related

Cassandra select all keys from map

I am trying to select keys from the courses map in the student table below
CREATE TABLE student (
studentid TEXT,
courses map<TEXT, TEXT>,
PRIMARY KEY (studentid)
);
With this data inserted
UPDATE student SET courses = courses + { 'bio101': 'Intro to Bio'} where studentid='xyz' ;
UPDATE student SET courses = courses + { 'bio102': 'Advanced Bio'} where studentid='xyz' ;
UPDATE student SET courses = courses + { 'chem101': 'Intro to Chem'} where studentid='xyz' ;
I would like to select only the keys in the courses map. So
courseId
--------
'bio101'
'bio102'
'chem101'
I've tried variations of
select courses from student where studentid='xyz';
but I can't seem to select just that column.
You can try to use UDF for this.
CREATE OR REPLACE FUNCTION keys (input Map<Text, Text>)
RETURNS NULL ON NULL INPUT
RETURNS Set<Text>
LANGUAGE java AS 'return input.keySet();';
You have to enable UDF because it disabled by default. Find enable_user_defined_functions in cassandra.yaml and replace false with true. Restart your Cassandra.
Change a little your query.
select keys(courses) from student where studentid='xyz';

How to use order by(Sorting) on Secondary index using Cassandra DB

My table schema is:
CREATE TABLE users
(user_id BIGINT PRIMARY KEY,
user_name text,
email_ text);
I inserted below rows into the table.
INSERT INTO users(user_id, email_, user_name)
VALUES(1, 'abc#test.com', 'ABC');
INSERT INTO users(user_id, email_, user_name)
VALUES(2, 'abc#test.com', 'ZYX ABC');
INSERT INTO users(user_id, email_, user_name)
VALUES(3, 'abc#test.com', 'Test ABC');
INSERT INTO users(user_id, email_, user_name)
VALUES(4, 'abc#test.com', 'C ABC');
For searching data into the user_name column, I created an index to use the LIKE operator with '%%':
CREATE CUSTOM INDEX idx_users_user_name ON users (user_name)
USING 'org.apache.cassandra.index.sasi.SASIIndex'
WITH OPTIONS = {
'mode': 'CONTAINS',
'analyzer_class': 'org.apache.cassandra.index.sasi.analyzer.NonTokenizingAnalyzer',
'case_sensitive': 'false'};
Problem:1
When I am executing below Query, it returns 3 records only, instead of 4.
select *
from users
where user_name like '%ABC%';
Problem:2
When I use below query, it gives an error as
ERROR: com.datastax.driver.core.exceptions.InvalidQueryException:
ORDER BY with 2ndary indexes is not supported.
Query =select * from users where user_name like '%ABC%' ORDER BY user_name ASC;
Query:
select *
from users
where user_name like '%ABC%'
ORDER BY user_name ASC;
My requirement is to filter the user_name with order by user_name.
The first query does work correctly for me using cassandra:latest which is now cassandra:3.11.3. You might want to double-check the inserted data (or just recreate from scratch using the cql statements you provided).
The second one gives you enough info - ordering by secondary indexes is not possible in Cassandra. You might have to sort the result set in your application.
That being said I would not recommend running this setup in real apps. With some additional scale (when you have many records) this will be a suicide performance-wise. I should not go into much detail since maybe you already understand this and SO is not a wikia/documentation site, so here is a link.

Chat - app (data model) with cassandra

I need to create chat between users using cassandra.
I have created table chat_messages like this :
create table chat_messages(
user_name text,
to_user text,
content text,
content_id uuid,
created_at timestamp,
primary key((user_name,to_user),created_at)
);
I want with one select get messages between two users.
insert into chat_messages(user_name, to_user, content, content_id, created_at) values('u1','u2','hi u2',uuid(),toTimestamp(now()));
insert into chat_messages(user_name, to_user, content, content_id, created_at) values('u2','u1','hi u1',uuid(),toTimestamp(now()));
I want to get hi u1 hi u2.
With your actual table structure you can use :
SELECT content
FROM chat_messages
WHERE user_name IN ('u1', 'u2')
AND to_user IN ('u1', 'u2');
But be careful using IN in WHERE clause because multiple nodes will be query.

Updating denormalized data in Cassandra

I'm trying to build a news feed system using Cassandra, I was thinking of using a fan out approach wherein if a user posts a new post, I'll write a new record in all of his friends' feed table. The table structure looks like:
CREATE TABLE users (
user_name TEXT,
first_name TEXT,
last_name TEXT,
profile_pic TEXT,
PRIMARY KEY (user_name)
);
CREATE TABLE user_feed (
user_name TEXT,
posted_time TIMESTAMP,
post_id UUID,
posted_by TEXT, //posted by username
posted_by_profile_pic TEXT,
post_content TEXT,
PRIMARY KEY ((user_name), posted_time)
) WITH CLUSTERING ORDER BY(posted_time desc);
Now, I can get a feed for a particular user in a single query all fine. What if the user who has posted a feed updates his profile pic. How do I go about updating the data in user_feed table?
You can use batch statements to achieve atomicity at your updates. So in this case you can create a batch with the update on tables users and user_feed using the same user_name partition key:
BEGIN BATCH
UPDATE users SET profile_pic = ? WHERE user_name = ?;
UPDATE user_feed SET posted_by_profile_pic = ? WHERE user_name = ?;
APPLY BATCH;
Take a look at CQL Batch documentation

Postgres sorting on timestamp works on mac but not linux

Using Postgres 9.4
I have a posts table which relates to a users table. I'm querying for two users and 3 of their most recent posts.
SELECT
"users"."id" AS "id",
"posts"."id" AS "posts__id",
"posts"."created_at" AS "posts__created_at"
FROM (
SELECT * FROM accounts
WHERE TRUE
ORDER BY "id" ASC
LIMIT 2
) AS "users"
LEFT JOIN LATERAL (
SELECT * FROM posts
WHERE "users".id = posts.author_id
ORDER BY "created_at" DESC, "id" DESC
LIMIT 3
) AS "posts" ON "users".id = "posts".author_id
On mac, the order is as expected.
"2016-04-17 18:49:15.942"
"2016-04-15 03:29:31.212"
"2016-04-13 15:07:15.119"
I get descending order on created_at, which is a timestamptz. However, when run on my travis build, which is Ubuntu, the ordering is stable, but neither ascending nor descending....
"2016-04-15 03:29:31.212"
"2016-04-13 15:07:15.119"
"2016-04-17 18:49:15.942"
I made user to create the databases with the same LC_COLLATE = en_US.UTF-8 with no luck. Why on earth isn't the ordering working on travis?
To solve this, just add the order by statement under your existing statements above.
i.e.
SELECT
"users"."id" AS "id",
"posts"."id" AS "posts__id",
"posts"."created_at" AS "posts__created_at"
FROM (
SELECT * FROM accounts
WHERE TRUE
ORDER BY "id" ASC
LIMIT 2
) AS "users"
LEFT JOIN LATERAL (
SELECT * FROM posts
WHERE "users".id = posts.author_id
ORDER BY "created_at" DESC, "id" DESC
LIMIT 3
) AS "posts" ON "users".id = "posts".author_id
order by posts.created_at desc
The order of output on postgres (and many other dbms's) cannot be guaranteed without an order by statement.
While you do indeed have order by statements, they are within sub-queries, you need the order by on the outer query.
you may need to order the outer query too because the in join between the 2 inner queries, even when they are ordered, won't be guaranteed.
SELECT
"users"."id" AS "id",
"posts"."id" AS "posts__id",
"posts"."created_at" AS "posts__created_at"
FROM (
SELECT * FROM accounts
WHERE TRUE
ORDER BY "id" ASC
LIMIT 2
) AS "users"
LEFT JOIN LATERAL (
SELECT * FROM posts
WHERE "users".id = posts.author_id
ORDER BY "created_at" DESC, "id" DESC
LIMIT 3
) AS "posts" ON "users".id = "posts".author_id
order by "posts"."created_at" DESC
Because the actual sort order depends on both the order of id in the first table and the order of the created_at & id in the second one prior to joining them. This means the order of the first table can produce unexpected results when computing the selected values from the joined table.
To fix the sort order, you should sort the final result set by relevant columns as well.

Resources