mysql subquery in select unknown column - mariadb

I have a subquery in the select statement that I need to find a count based on the base query. If I hard code the course_id that needing the count for it works (other then the count is for just the same course not all listed) but when I change it to use the listed course_id it returns the 1054 - Unknown column error.
Error SQL
SELECT
c.course_id,
c.course_name,
(SELECT COUNT(wpt_users_id)
FROM (SELECT course_activity.wpt_users_id, course_activity.course_id, min(course_activity.course_activity_entry_dt)
FROM wpt_user_subscriptions
JOIN course_activity ON course_activity.wpt_users_id = wpt_user_subscriptions.wpt_users_id
WHERE wpt_user_subscriptions.wpt_subscription_id = 35
AND course_activity.course_id = c.course_id
GROUP BY course_activity.wpt_users_id, course_activity.course_id) sub1) as course_count
FROM `wpt_subscription_course` sc
JOIN course c ON c.course_id = sc.course_id
WHERE sc.`wpt_subscription_id` = 35
Returns: MySQL said: #1054 - Unknown column 'c.course_id' in 'where clause'
Will run SQL:
SELECT
c.course_id,
c.course_name,
(SELECT COUNT(wpt_users_id)
FROM (SELECT course_activity.wpt_users_id, course_activity.course_id, min(course_activity.course_activity_entry_dt)
FROM wpt_user_subscriptions
JOIN course_activity ON course_activity.wpt_users_id = wpt_user_subscriptions.wpt_users_id
WHERE wpt_user_subscriptions.wpt_subscription_id = 35
AND course_activity.course_id = 9
GROUP BY course_activity.wpt_users_id, course_activity.course_id) sub1) as course_count
FROM `wpt_subscription_course` sc
JOIN course c ON c.course_id = sc.course_id
WHERE sc.`wpt_subscription_id` = 35
Any thoughts to why it's not working when it's spelled correctly yet not working.
Environment specs:
[[Database server]]
Server type: MariaDB
Server version: 5.5.41-MariaDB - MariaDB Server
Protocol version: 10
[[phpMyAdmin]]
Version information: 4.4.8, latest stable version: 4.4.10
[[Web server]]
Apache/2.4.6 (CentOS) PHP/5.4.16
Database client version: libmysql - 5.5.41-MariaDB
PHP extension: mysqli Documentation
PHP version: 5.4.16
Thanks.

A bit more indentation makes it more obvious:
SELECT c.course_id, c.course_name,
( SELECT COUNT(wpt_users_id)
FROM
( SELECT ca.wpt_users_id, ca.course_id,
min(ca.course_activity_entry_dt)
FROM wpt_user_subscriptions AS wus
JOIN course_activity AS ca ON ca.wpt_users_id =
wus.wpt_users_id
WHERE wus.wpt_subscription_id = 35
AND ca.course_id = c.course_id -- HERE
GROUP BY ca.wpt_users_id, ca.course_id
) sub1
) as course_count
FROM `wpt_subscription_course` sc
JOIN course c ON c.course_id = sc.course_id -- HERE
WHERE sc.`wpt_subscription_id` = 35
I think subqueries can see tables only in the immediately surrounding query.
Maybe this works and gets the right answers??
SELECT c.course_id, c.course_name, course_count
FROM `wpt_subscription_course` sc
JOIN course c ON c.course_id = sc.course_id
JOIN
( SELECT COUNT(*) course_count, ca.wpt_users_id, ca.course_id,
min(ca.course_activity_entry_dt)
FROM wpt_user_subscriptions AS wus
JOIN course_activity AS ca ON ca.wpt_users_id = wus.wpt_users_id
WHERE wus.wpt_subscription_id = 35
AND ca.course_id = c.course_id
GROUP BY ca.wpt_users_id, ca.course_id
) sub1
WHERE sc.`wpt_subscription_id` = 35

Related

mariadb alternative to outer apply or lateral?

What I wanted was to use CROSS APPLY, but I guess that doesn't exist in mysql. The alternative I've read is LATERAL. Well, I'm using mariadb 10.3 and I guess that doesn't exist either. The ticket table contains an id that's referenced by the ticket_id column in the note table. A ticket can have many notes, I'm trying to list all tickets with their most recent note date (post_date). How could I write the query below for mariadb?
SELECT t.*, n.post_date
FROM ticket t,
LATERAL (
SELECT note.post_date FROM note WHERE t.id = note.ticket_id ORDER BY note.post_date DESC LIMIT 1
) n;
Example table structure:
Ticket
id
subject
1
stuff
2
more
note
id
post_date
ticket_id
1
1
2
1
3
2
4
1
5
2
I did find an open jira ticket from people asking for mariadb to support lateral.
From what I read, LATERAL will not be supported in MariaDB until version 11. But we can just as easily use ROW_NUMBER here, which is supported:
WITH cte AS (
SELECT *, ROW_NUMBER() OVER (PARTITION BY ticket_id ORDER BY post_date DESC) rn
FROM note
)
SELECT t.*, n.post_date
FROM ticket t
INNER JOIN cte n
ON n.ticket_id = t.id
WHERE n.rn = 1;
If you wanted a close translation of your current lateral join, then use:
SELECT t.*,
(SELECT n.post_date
FROM note n
WHERE t.id = note.ticket_id
ORDER BY n.post_date DESC
LIMIT 1)
FROM ticket t;

Update another table using output of cte in teradata

Technology: Teradata 16.20
I'm trying to update a table, that takes data from another table which uses CTE data.
I'm getting below error:
Error:
select failed 3707 syntax error, expected something like a 'SELECT' keyword or '(' or a 'TRANSACTIONTIME' keyword or a 'VALIDTIME' keyword between ')' and the 'UPDATE' keyword
Question:
Is it possible to update a table using another table that is getting joined with cte?
I know it can be done with a volatile table. I have seen CTE with insert statement and with select statement, but never seen cte with an update statement. Writing the same sql over and over for multiple self join only increases the lines of code. If this update can be done using CTE, that would be much easier and understandable
Code:
WITH NAME_CTE AS (
SELECT FIRST.ID,FIRST.NAM,LAST.NAME
FROM TABLE_FIRST FIRST INNER JOIN TABLE_LAST LAST
ON FIRST.ID = LAST.ID
)
UPDATE SUBJECT_TEACHER_TABLE
FROM (
SELECT CROSS_TBL.SUB_ID,
COALESCE(CTE1.NAM,CTE1.NAME,CTE2.NAM,CTE2.NAME) AS FINAL_NAME
FROM CROSS_REFERENCE_TABLE CROSS_TBL
LEFT JOIN NAME_CTE CTE1 ON CROSS_TBL.CR_ID1 = CTE.ID
LEFT JOIN NAME_CTE CTE2 ON CROSS_TBL.CR_ID2 = CTE.ID
) PV
SET
FINAL_NAME = PV.FINAL_NAME
WHERE SUBJECT_TEACHER_TABLE.SUB_ID = PV.SUB_ID;
Modified Query: As per #dnoeth suggesstion
UPDATE SUBJECT_TEACHER_TABLE
FROM (
WITH NAME_CTE AS (
SELECT FIRST.ID,FIRST.NAM,LAST.NAME
FROM TABLE_FIRST FIRST INNER JOIN TABLE_LAST LAST
ON FIRST.ID = LAST.ID)
SELECT CROSS_TBL.SUB_ID,
COALESCE(CTE1.NAM,CTE1.NAME,CTE2.NAM,CTE2.NAME) AS FINAL_NAME
FROM CROSS_REFERENCE_TABLE CROSS_TBL
LEFT JOIN NAME_CTE CTE1 ON CROSS_TBL.CR_ID1 = CTE.ID
LEFT JOIN NAME_CTE CTE2 ON CROSS_TBL.CR_ID2 = CTE.ID
) PV
SET
FINAL_NAME = PV.FINAL_NAME
WHERE SUBJECT_TEACHER_TABLE.SUB_ID = PV.SUB_ID;
Error:
SQL Error [3807] [42S02]: [Teradata Database] [TeraJDBC 15.10.00.22] [Error 3807] [SQLState 42S02] Object 'NAME_CTE' does not exist.

sqlite3 : Compare two cells from the same table

I have a table like this
CREATE TABLE "modules" ( `ID` INTEGER PRIMARY KEY AUTOINCREMENT, `name` TEXT, `version` TEXT, `deployID` INTEGER )
I want to be able to get all the rows from this database where the version is different between different deploy ID's. So, say I have a deploy ID 2 and a deployID 3 - my table might have 2000 odd modules for each of these deploys. I want to only get the rows where the name is the same but the version is different. Is this possible? I thought this query would do it but it seems to be returning me everything - twice!
SELECT a.* FROM modules a
INNER JOIN modules b
ON a.name == b.name
WHERE a.version != b.version
AND a.deployID = 3
AND b.deployID = 2
If you only care about deployids 2 and 3:
select m.*
from modules m
where
m.deployid in (2, 3)
and
exists (
select 1 from modules
where
name = m.name
and
deployID <> m.deployID
and
version <> m.version
)
If you don't need this condition:
deployID <> m.deployID
you can remove it.
I would probably use an exists query here:
SELECT m1.*
FROM modules m1
WHERE EXISTS (SELECT 1 FROM modules m2
WHERE m1.name = m2.name AND
m1.deployID <> m2.deployID AND m1.version <> m2.version);
Or maybe you want a more specific version:
SELECT m1.*
FROM modules m1
WHERE EXISTS (SELECT 1 FROM modules m2
WHERE m1.name = m2.name AND
LEAST(m1.deployID, m2.deployID) = 2 AND
GREATEST(m1.deployID, m2.deployID) = 3);

Teradata 16 Issues

We recently upgraded our Teradata version to 16 and since then we are facing few spool space issues. Before the query was consuming less then 200GB and now it consumes more than 1.5TB. We then started optimizing the query and we modified a part of the query
LEFT JOIN (SELECT A.XX, C.YY FROM TABLE1 A
INNER JOIN TABLE2 B ON A.DD = B.EE
INNER JOIN TABLE3 C ON C.FF = B.GG
GROUP BY 1,2)
to
LEFT JOIN (SELECT A.XX, C.YY FROM TABLE1 A
INNER JOIN TABLE2 B ON A.DD = B.EE
INNER JOIN (SELECT FF, YY FROM TABLE3 GROUP BY 1,2) C
ON C.FF = B.GG
GROUP BY 1,2)
After modification the query runs within 200GB. Could someone please explain as why we face such issues after upgrade? Thanks in advance.

Update Rows based on JOIN results

I can't get the following query to work:
UPDATE ISSUE
SET DUE_DATE = DATE(ISSUE.DATE_ADDED,'+90 day')
JOIN CVE on CVE.CVE_ID = ISSUE.CVE_ID
WHERE CVE.CVSS >= 4 AND CVE.CVSS < 9
This is because in sqlite3 you can't join in an UPDATE. What I'm trying to do is set the due date of an issue to be 90 days after the date added if the CVE associated with the issue is: greater than or equal to four and less than 9. Is there an alternative option that I'm missing here?
You can join the rows in a sub-query.
UPDATE ISSUE
SET DUE_DATE = DATE(ISSUE.DATE_ADDED,'+90 day')
WHERE ISSUE.CVE_ID IN (
SELECT ISSUE.CVE_ID
FROM ISSUE JOIN CVE on CVE.CVE_ID = ISSUE.CVE_ID
WHERE CVE.CVSS >= 4 AND CVE.CVSS < 9
)

Resources