SQLite - Left Join with Substr - sqlite

select distinct substr(value,2,4),summary
from ticket_custom
LEFT JOIN ticket On ticket_custom.substr(value,2,4) = ticket.id
where name = "parent" AND value <> 0
I have a table ticket_custom where the ticket-number has a hastag in front of the ticketnumber (e.g. "#4567"), but in the table ticket, the ticketnumber is saved without this hashtag ("4567").
I would like to left join these two tables and would like to use the "summary"-value of the table ticket right next to the ticket-number without the #. I tried the above query, but I am getting an error. How can I combine substr = using the ticketnumber without the # with a left join? Or is there another way to do this?
Thanks!

You should be doing substr(ticket_custom.value,2) instead of ticket_custom.substr(value,2,4) (syntax was incorrect, and string length isn't guaranteed only to be 5 chars)
So your query should look like:
select distinct substr(value,2),summary
from ticket_custom
LEFT JOIN ticket On substr(ticket_custom.value,2) = ticket.id
where name = "parent" AND value <> 0

This is the correct syntax for the function substr():
On substr(ticket_custom.value,2,4) = ticket.id
or
On substr(ticket_custom.value,2) = ticket.id
if ticket_custom.value contains only 5 characters.
In this case (only 5 characters) you can use replace():
On replace(ticket_custom.value, '#', '') = ticket.id
or simply:
On ticket_custom.value = '#' || ticket.id

Related

Oracle Json object DISTINCT keep getting repeating columns

So i have a query and it need to return a JSON object but the DISTINCT doesn't work no matter what I try. I've been trying a series of other tests and no matter what the 'WBS' always shows up with 3 or more duplicated columns. Anyone got any ideas?
I am working in Asp.net 6 MVC
PROCEDURE GET_BASELINE_RPT (in_WBS_LEVEL_ID IN NUMBER, in_FISCAL_YEAR IN VARCHAR2,
in_FISCAL_MONTH IN VARCHAR2, RET OUT CLOB) AS
BEGIN
WITH cte AS (
SELECT /*+MATERIALIZE*/ DISTINCT L.WBS_LEVEL_ID
FROM
WBS_LEVEL L
)
SELECT
JSON_ARRAYAGG (
JSON_OBJECT (
'WBS' VALUE L.WBS_LEVEL_NAME,
'Title' VALUE W.DESCRIPTION,
'Rev' VALUE B.REV_NUMBER,
'ScopeStatus' VALUE W.STATUS,
'BCP' VALUE CASE WHEN BC.FISCAL_YEAR = 0 THEN '' ELSE
SUBSTR(BC.FISCAL_YEAR,3,2)||'-'||LPAD(BC.BCP_FISCAL_ID, 3, '0') END,
'BCPApprovalDate' VALUE BC.APPROVAL_DATE,
'Manager' VALUE P1.NICK_NAME,
'ProjectControlManager' VALUE P2.NICK_NAME,
'ProjectControlEngineer' VALUE P3.NICK_NAME,
'FiscalYear' VALUE W.FISCAL_YEAR,
'FiscalMonth' VALUE W.FISCAL_MONTH,
'WBSNumber' VALUE L.WBS_LEVEL_ID
)RETURNING CLOB)
INTO RET
FROM WBS_LEVEL L
LEFT OUTER JOIN BASELINE_RPT B ON L.WBS_LEVEL_ID = B.WBS_LEVEL_ID
JOIN BCP BC ON BC.BCP_ID = B.BCP_ID
LEFT OUTER JOIN WBS_TREE_MOD W ON L.WBS_LEVEL_ID = W.WBS_LEVEL_ID
LEFT OUTER JOIN VW_SITEPEOPLE P1 ON W.WBS_MANAGER_SNUMBER = P1.SNUMBER
LEFT OUTER JOIN VW_SITEPEOPLE P2 ON W.PCM_SNUMBER = P2.SNUMBER
LEFT OUTER JOIN VW_SITEPEOPLE P3 ON W.PCE_SNUMBER = P3.SNUMBER
ORDER BY L.WBS_LEVEL_NAME, B.REV_NUMBER DESC;
END GET_BASELINE_RPT;
so it turns out I wasn't getting duplicates at all. There were differences in the data but there were so many columns that had the same data that I didn't notice the differences until another review. I will try to restart my query but to be honest I may just put in a filter in my C#.

Cannot replace a string with several random strings taken from another table in sqlite

I'm trying to replace a placeholder string inside a selection of 10 random records with a random string (a name) taken from another table, using only sqlite statements.
i've done a subquery in order to replace() of the placeholder with the results of a subquery. I thought that each subquery loaded a random name from the names table, but i've found that it's not the case and each placeholder is replaced with the same string.
select id, (replace (snippet, "%NAME%", (select
name from names
where gender = "male"
) )
) as snippet
from imagedata
where timestamp is not NULL
order by random()
limit 10
I was expecting for each row of the SELECT to have different random replacement every time the subquery is invoked.
hello i'm %NAME% and this is my house
This is the car of %NAME%, let me know what you think
instead each row has the same kind of replacement:
hello i'm david and this is my house
This is the car of david, let me know what you think
and so on...
I'm not sure it can be done inside sqlite or if i have to do it in php over two different database queries.
Thanks in advance!
Seems that random() in the subquery is only evaluated once.
Try this:
select
i.id,
replace(i.snippet, '%NAME%', n.name) snippet
from (
select
id,
snippet,
abs(random()) % (select count(*) from names where gender = 'male') + 1 num
from imagedata
where timestamp is not NULL
order by random() limit 10
) i inner join (
select
n.name,
(select count(*) from names where name < n.name and gender = 'male') + 1 num
from names n
where gender = 'male'
) n on n.num = i.num

Counting 2 Columns from Separate Tables Between 2 Dates

I have a query that Counts 2 columns from 2 separate tables using subqueries, which works. Now I have to implement into this query the ability to filter out these results based on the Date of a Call Record. I will post the query in which I am working with:
SELECT (m.FirstName || " " || m.LastName) AS Members,
(
SELECT count(CallToLineOfficers.MemberID)
FROM CallToLineOfficers
WHERE CallToLineOfficers.MemberID = m.MemberID
)
+ (
SELECT count(CallToMembers.MemberID)
FROM CallToMembers
WHERE CallToMembers.MemberID = m.MemberID
) AS Tally
FROM Members AS m, Call, CallToMembers, CallToLineOfficers
Join Call on CallToMembers.CallID = Call.CallID
and CallToLineOfficers.CallID = Call.CallI
WHERE m.FirstName <> 'None'
-- and Call.Date between '2017-03-21' and '2017-03-22'
GROUP BY m.MemberID
ORDER BY m.LastName ASC;
Ok, so table Call stores the Date and its PK is CallID. Both CallToLineOfficers and CallToMembers are Bridge Tables that also contain only CallID and MemberID. With the current query, where the Date is commented out, that Date range should only return all names, but a count of 1 should appear under 1 person's name.
I have tried joining Call.CallID with both Bridge Tables' CallIDs without any luck, though I think this is the right way to do it. Could someone help point me in the right direction? I am lost. (I tried explaining this the best I could, so if you need more info, let me know.)
UPDATED: Here is a screenshot of what I am getting:
Based on the provided date in the sample, the new results, with the Date, should be:
Bob Clark - 1
Rob Catalano - 1
Matt Butler - 1
Danielle Davidson - 1
Jerry Chuska - 1
Tom Cramer - 1
Everyone else should be 0.
At the moment, the subqueries filter only on the member ID. So for any member ID in the outer query, they return the full count.
To reduce the count, you have to filter in the subqueries:
SELECT (FirstName || " " || LastName) AS Members,
(
SELECT count(*)
FROM CallToLineOfficers
JOIN Call USING (CallID)
WHERE MemberID = m.MemberID
AND Date BETWEEN '2017-03-21' AND '2017-03-22'
)
+ (
SELECT count(*)
FROM CallToMembers
JOIN Call USING (CallID)
WHERE MemberID = m.MemberID
AND Date BETWEEN '2017-03-21' AND '2017-03-22'
) AS Tally
FROM Members AS m
WHERE FirstName <> 'None'
ORDER BY LastName ASC;

How can I use the same name for a column in the output of my sqlite query as a value I am comparing to in the join's ON clause?

My original question
When I execute the following query in SQLite, I get this error:
Query Error: misuse of aggregate: sum() Unable to execute statement
When I change the name of the "Loan" column to something like loan_amount the error goes away and my query works fine. Why is there a problem with "Loan"?
select
t.*
, coalesce(sum(ded0.after_tax_ded_amt), 0) as "Loan"
, coalesce(sum(ded1.after_tax_ded_amt), 0) as ee_advance_amount
from totals t
left join totals as ded0
on t.ee_ssn = ded0.ee_ssn
and t.deduction_code = "Loan"
and ded0.deduction_code = "Loan"
left join totals as ded1
on t.ee_ssn = ded1.ee_ssn
and t.deduction_code = "EE Advance"
and ded1.deduction_code = "EE Advance"
group by t.ee_ssn;
Mid-post revelation
I'm pretty sure I figured out why I get the error, is it because I am comparing to "Loan" in the on-clause of my joins?
If so, how can I still use the word "Loan" for my column name in the output of my query?
I'd guess that your real problem is quote misuse. Single quotes in SQL are for quoting string literals, double quotes are for quoting column and table names that need to be case sensitive or contain odd characters. SQLite is fairly forgiving of odd syntax so it is probably making a guess about what "Loan" means and guessing incorrectly. Try this:
select
t.*
, coalesce(sum(ded0.after_tax_ded_amt), 0) as "Loan"
, coalesce(sum(ded1.after_tax_ded_amt), 0) as ee_advance_amount
from totals t
left join totals as ded0
on t.ee_ssn = ded0.ee_ssn
and t.deduction_code = 'Loan'
and ded0.deduction_code = 'Loan'
left join totals as ded1
on t.ee_ssn = ded1.ee_ssn
and t.deduction_code = 'EE Advance'
and ded1.deduction_code = 'EE Advance'
group by t.ee_ssn;

Querying on count value having ()

I'm having difficulty with a query which displays records according to their fill rate.
For instance, a vacancy can have no bookings or some bookings. If a vacancy has bookings, they can be in the form of 'active [1]', 'pending [0]'. The query I have written so far works if the vacancy has booking records but I can't get it to work if it doesn't have booking records.
My query (which works) for vacancies with a booking is as follows:-
SELECT v.*, j.job_category_name, bu.business_unit_name
FROM vacancy v
INNER JOIN job_category j ON j.job_category_id = v.job_category_id
INNER JOIN business_unit bu ON bu.business_unit_id = v.business_unit_id
INNER JOIN booking b ON b.vacancy_id = v.vacancy_id
INNER JOIN booking_status bs ON bs.id = b.booking_status_id
WHERE
v.vacancy_status <> 'revoked' AND
v.vacancy_reference <> 'auto-generated booking' AND
v.business_unit_id IN (series of primary keys) AND
(bs.booking_status_type_id = 1 OR bs.booking_status_type_id = 2)
GROUP BY v.vacancy_id
HAVING v.vacancy_limit > count(b.booking_id)
ORDER BY v.vacancy_id DESC
I thought by changing the join of b and bs to LEFT JOIN would have worked, but it hasn't.
Any ideas?
Without a copy of your schema to work from, it's difficult to tell exactly, but when you changed booking and bookingstatus to LEFT JOINs, did you also modify your WHERE clause so that it read something like:
WHERE
v.vacancy_status <> 'revoked' AND
v.vacancy_reference <> 'auto-generated booking' AND
v.business_unit_id IN (series of primary keys) AND
(ISNULL(bs.booking_status_type_id, 1) = 1 OR ISNULL(bs.booking_status_type_id, 2) = 2)
i.e. Ensured that the full WHERE clause would be satisfied, thus not stripping out the records where all the values for columns from booking and bookingstatus were NULL?
Try LEFT OUTER JOIN for the tables for which the joins may return 0 matches.
For eg:- in your case have LEFT OUTER JOIN for b and bs and check

Resources