How to find position of User in query ?
I have ( I am using MySQL)
session.query(UserModel).order_by(desc(UserModel.age)).all()
and I have user id, how to find position of that specific id is ordered array ?
( I can return all and iterate but is there uicker way to solve this on database level, need to run fast)
Database should support window functions to do this. Raw SQL query will look like this:
SELECT pos FROM
(SELECT id, row_number() OVER (ORDER BY age DESC) AS pos FROM user) AS sub
WHERE sub.id = :id;
In SQLAlchemy:
from sqlalchemy import func, desc
user_id = 42
sub = (session
.query(
UserModel.id,
func.row_number().over(order_by=desc(UserModel.age)).label('pos'))
.subquery())
pos = session.query(sub.c.pos).filter(sub.c.id==user_id).scalar()
Note that returned index is 1-based.
Among popular RDBMS this will work in PostgreSQL, Oracle, MSSQL, but not in MySQL or SQLite.
Related
(SELECT schemename, message FROM RandomMessagesSet where type = 'ES' ORDER BY RAND())
UNION ALL (SELECT schemename, message FROM RandomMessagesSet where type = 'HE' ORDER BY RAND()) ORDER BY schemename;
This gives the list of all the messages with their scheme names. Is there a way to get 3 each of type "ES" and 2 each of type "HE" for each of schemename?
This is not a homework but part of a research problem that would feed into designing a user study. I tried using LIMIT and JOIN by looking at most of the posts here but still stuck.
Please help me. Your help would assist me to design my second last experiment for my PhD.
EDIT: Thanks to the most empathetic person who downvoted this. You should try doing a PhD yourself to get the feel of it.
I'm afraid I cannot provide sample data due to nature of research work.
Desired output:
In MySQL 8.0 and above, we can use Window Functions. We use a Partition over an expression of concatenated string of schemename and type.
Try (DB Fiddle):
SELECT dt.schemename,
dt.type,
dt.message
FROM
(
SELECT
schemename,
type,
message,
ROW_NUMBER() OVER (PARTITION BY CONCAT(schemename, '-', type)
ORDER BY RAND()) AS row_num
FROM RandomMessagesSet
) AS dt
WHERE (dt.type = 'ES' AND dt.row_num <= 3) OR
(dt.type = 'HE' AND dt.row_num <= 2)
ORDER BY dt.schemename
My problem is the following, I want set a list of ID in a variable, then use this variable in a subquery. The problem is that WorkBench (my GUI) return the following error : "subquery returning multiple rows". It seems to me that's what I want.
Please explain me where I am wrong.
This is my query :
set #listID := (select ID_VOIE as ID from voies
where ORIGINE = 'XXX'
group by CODE_INSEE, CODE_VOIE
having count(*) > 1);
select substring(v.CODE_INSEE,1,2), count(*) from voies v
where v.ID_VOIE in (#listID)
group by substring(vs.CODE_INSEE,1,2);
The thing is I'm blocked with the "group by", I want do a groupd by after a first group by, that's why I can't (or at least i didn't find a way) write the request with a single WHERE clause.
The thing is I know that I can put the whole request directly in my subquery instead of using variable but :
It can let me use this trick in another requests that needed this behaviour (DRY concept !)
I'm not sure but the subquery will be executed in each turn of my loop, and that will be very inefficient
So I seek 2 possible ways : a way that let me use a list in a variable in a subquery OR a way that let me use "group by" twice in a single query.
Thanks you in advance for your answers (oh and sorry for my english, this is not my maternal language).
Unless you need that variable for something else, you should be able to skip it entirely as follows:
SELECT
SUBSTRING(v.CODE_INSEE,1,2),
COUNT(*)
FROM
voies v
WHERE
v.ID_VOIE in
(SELECT
ID_VOIE as ID
FROM
voies
WHERE
ORIGINE = 'XXX'
GROUP BY
CODE_INSEE,
CODE_VOIE
HAVING COUNT(*) > 1)
GROUP BY
SUBSTRING(vs.CODE_INSEE,1,2);
As you say, the subquery will be executed for all rows. To avoid that, a variable would be best, but MySQL doesn't support table variables. Instead, you can use a temporary table:
IF EXISTS DROP TABLE myTempTable;
CREATE TEMPORARY TABLE myTempTable (ID_VOIE int); -- I don't know the datatype
INSERT INTO myTempTable (ID_VOIE)
SELECT DISTINCT -- using distinct so I can join instead of use IN.
ID_VOIE as ID from voies
WHERE
ORIGINE = 'XXX'
GROUP BY
CODE_INSEE, CODE_VOIE
HAVING COUNT(*) > 1
And now you can do this:
SELECT
SUBSTRING(v.CODE_INSEE,1,2), COUNT(*)
FROM
voies v
JOIN myTempTable tt ON
v.ID_VOIE = tt.ID_VOIE
GROUP BY SUBSTRING(vs.CODE_INSEE,1,2);
I have a location table in my database which contains location data of all the users of my system.
The table design is something like
id| user_id| longitude| latitude| created_at|
I have an array of users. Now I want to select the latest(sorted according to created at) location of all these users.
I am able to figure out the sql query for same
SELECT * FROM my_table
WHERE (user_id , created_at) IN (
SELECT user_id, MAX(created_at)
FROM my_table
GROUP BY user_id
)
AND user_id IN ('user1', 'user2', ... );
Now as I am working in Ruby On Rails, I want to write this sql query to activerecord rails. Can anyone please help me with this ?
I think this will give the correct result:
MyModel.order(created_at: :desc).group(:user_id).distinct(:user_id)
If you want to generate the exact same query, this will do it:
MyModel.where("(user_id, created_at) IN (SELECT user_id, MAX(created_at) from my_table GROUP BY user_id)")
I think the subquery will probably not scale well with a large data set, but I understand if you just want to get it into rails and optimize later.
How about adding a scope, and getting the same result in a slightly different way:
class UserLocation
def self.latest_per_user
where("user_locations.created_at = (select Max(ul2.created_at) from user_locations ul2 where ul2.user_id = user_locations.user_id)")
end
end
Then you just use:
UserLocation.latest_per_user.where(:user_id => ['user1', 'user2'])
... to get the required data set.
I have created the following HIVE code and require to translate it to use in scala. From what I understand we need to use sqlContext.sql
The examples available online only have simple select statements.Like the example below.
For example to run a simple sql query in scala:
val tableA = sqlContext.sql("Select * from game");
I can't seem to use the same syntax for the code below.What is the syntax to translate the code below to fit the above usage.
DROP TABLE ADW.TERA_BARCODE_LOOKUP_TABLE_RAW ;
CREATE TABLE ADW.TERA_BARCODE_LOOKUP_TABLE_RAW AS
SELECT CAST(BRCDE_REF_I AS STRING) AS BARCODE,
MAX(TRIM(GST_SRC_ID)) AS GST_SRC_ID,MAX(SRC_ACTV_TS) AS SRC_ACTV_TS
FROM
(SELECT RANKED.*
FROM
(SELECT BRCDE_REF_I,GST_SRC_ID,SRC_ACTV_TS,
RANK() over (partition by BRCDE_REF_I ORDER BY SRC_ACTV_TS DESC) AS RANK
FROM
ADW.GST_SRC_ID_BRCDE_LKUP_TABLE X
WHERE UPPER(X.CURR_ACTV_F) = 'Y' AND TRIM(X.GST_SRC_ID) IN
(SELECT TRIM(GST_SRC_I) FROM ADW.CANDIDATE_GST_ID_SRC_TABLE GROUP BY TRIM(GST_SRC_I))
) RANKED
WHERE RANKED.RANK = 1 ) X
GROUP BY BRCDE_REF_I ;
There are two SQL commands, and because Apache Hive doesn't support BEGIN and COMMIT best option for you will be to put it into two commands.
You have not posted your error. I assumed you could also got error on DROP TABLE, so changed it to DROP TABLE IF EXISTS.
Also, in Scala to use multiline strings, you have to wrap them with """, not ".
sqlContext.sql("DROP TABLE IF EXISTS ADW.TERA_BARCODE_LOOKUP_TABLE_RAW")
sqlContext.sql("""
CREATE TABLE ADW.TERA_BARCODE_LOOKUP_TABLE_RAW AS
SELECT CAST(BRCDE_REF_I AS STRING) AS BARCODE,
MAX(TRIM(GST_SRC_ID)) AS GST_SRC_ID,MAX(SRC_ACTV_TS) AS SRC_ACTV_TS
FROM
(SELECT RANKED.*
FROM
(SELECT BRCDE_REF_I,GST_SRC_ID,SRC_ACTV_TS,
RANK() over (partition by BRCDE_REF_I ORDER BY SRC_ACTV_TS DESC) AS RANK
FROM
ADW.GST_SRC_ID_BRCDE_LKUP_TABLE X
WHERE UPPER(X.CURR_ACTV_F) = 'Y' AND TRIM(X.GST_SRC_ID) IN
(SELECT TRIM(GST_SRC_I) FROM ADW.CANDIDATE_GST_ID_SRC_TABLE GROUP BY TRIM(GST_SRC_I))
) RANKED
WHERE RANKED.RANK = 1 ) X
GROUP BY BRCDE_REF_I
""")
Commutative property describes itself as for example a(bc) = (ab)c.
Considering this example, how can we get commutative relation from SELECT statement in MySQL particularly. So far, I am clearly unable to execute the following query.
SELECT name from (
SELECT name from employee WHERE id = 5;
)