Convert Xpath to SQL - sql

Previously we were fetching a number of countries from a table. Now the table changed to support multiple languages inside the text cell. The previous SQL statement was:
select b.text, a.iso_num, a.iso2, a.iso3, a.kfz, a.ind_member
from schema.zl_countrycode a, schema.zl_countrycode_lsd b
where a.ind_land = 1 and a.kfz is not NULL and dat_end = to_date('99991231','YYYYMMDD') and a.ZL_COUNTRYCODE_id = b.ZL_COUNTRYCODE_LSD_ID order by text
The list previously outputted each country in a row.
With the addition of the language selection, the list suddenly doubled in size - because it lists every county in two different languages.
This is how the table looks with the GUI
I'm trying to figure out, how to expend the statement to only select each "DE:" value in the text column. After having a quick indirect discussion with the developers, they provided me this XPATH statement:
Parentofparent/Parent/Valuestable[name="ZL_COUNTRYCODE"]/Valueclassification[name="TEXT"]/Value/ValueLng[lng="DE"]
I don't know the first thing about XPATH and no matter what I have tried so far, it failed.
Please help me out if you're knowledgeable in this field. It's probably an Oracle database, as I have experienced a plethora of Oracle error codes in the last few days.

I think this should do the trick:
SELECT b.TEXT
,a.iso_num
,a.iso2
,a.iso3
,a.kfz
,a.ind_member
,a.de
FROM SCHEMA.zl_countrycode a
JOIN SCHEMA.zl_countrycode_lsd b
ON a.ZL_COUNTRYCODE_id = b.ZL_COUNTRYCODE_LSD_ID AND b.spec_lng = 'DE'
WHERE a.ind_land = 1
AND a.kfz IS NOT NULL
AND dat_end = to_date('99991231', 'YYYYMMDD')
ORDER BY TEXT

Related

SQL query find few strings in diferent columns in a table row (restrictive)

I have a table like this one (in a SQL SERVER):
field_name
field_descriptor
tag1
tag2
tag3
tag4
tag5
house
your home
home
house
null
null
null
car
first car
car
wheel
null
null
null
...
...
...
...
...
...
...
I'm developing a WIKI with a searchbar, which should be able to handle a query with more than one string for search. As an user enters a second string (spaced) the query should be able to return results that match restrictively the two strings (if exists) in any column, and so with a three string search.
Easy to do for one string with a simple SELECT with ORs.
Tried in the fronted in JS with libraries like match-sorter but it's heavy with a table with more than 100,000 results and more in the future.
I thought the query should do the heavy work, but maybe there is no simple way doing it.
Thanks in advance!
Tried to do the heavy work with all results in frontend with filtering and other libraries like match-sorter. Works but take several seconds and blocks the front.
Tried to create a simple OR/AND query but the posibilities with 3 search-strings (could be 1, 2 or 3) matching any column to any other possibility is overwhelming.
You can use STRING_SPLIT to get a separate row per search word from the search words string. Then only select rows where all search words have a match.
The query should look like this:
select *
from mytable t
where exists
(
select null
from (select value from string_split(#search, ' ')) search
having min(case when search.value in (t.tag1, t.tag2, t.tag3, t.tag4, t.tag5) then 1 else 0 end) = 1
);
Unfortunately, SQL Server seems to have a flaw (or even a bug) here and reports:
Msg 8124 Level 16 State 1 Line 8
Multiple columns are specified in an aggregated expression containing an outer reference. If an expression being aggregated contains an outer reference, then that outer reference must be the only column referenced in the expression.
Demo: https://dbfiddle.uk/kNL1PVOZ
I don't have more time at hand right now, so you may use this query as a starting point to get the final query.

SQL Query for Search Page

I am working on a small project for an online databases course and i was wondering if you could help me out with a problem I am having.
I have a web page that is searching a movie database and retrieving specific columns using a movie initial input field, a number input field, and a code field. These will all be converted to strings and used as user input for the query.
Below is what i tried before:
select A.CD, A.INIT, A.NBR, A.STN, A.ST, A.CRET_ID, A.CMNT, A.DT
from MOVIE_ONE A
where A.INIT = :init
AND A.CD = :cd
AND A.NBR = :num
The way the page must search is in three different cases:
(initial and number)
(code)
(initial and number and code)
The cases have to be independent so if certain field are empty, but fulfill a certain case, the search goes through. It also must be in one query. I am stuck on how to implement the cases.
The parameters in the query are taken from the Java parameters in the method found in an SQLJ file.
If you could possibly provide some aid on how i can go about this problem, I'd greatly appreciate it!
Consider wrapping the equality expressions in NVL (synonymous to COALESCE) so if parameter inputs are blank, corresponding column is checked against itself. Also, be sure to kick the a-b-c table aliasing habit.
SELECT m.CD, m.INIT, m.NBR, m.STN, m.ST, m.CRET_ID, m.CMNT, m.DT
FROM MOVIE_ONE m
WHERE m.INIT = NVL(:init, m.INIT)
AND m.CD = NVL(:cd, m.CD)
AND m.NBR = COALESCE(:num, m.NBR)
To demonstrate, consider below DB2 fiddles where each case can be checked by adjusting value CTE parameters all running on same exact data.
Case 1
WITH
i(init) AS (VALUES('db2')),
c(cd) AS (VALUES(NULL)),
n(num) AS (VALUES(53)),
cte AS
...
Case 2
WITH
i(init) AS (VALUES(NULL)),
c(cd) AS (VALUES(2018)),
n(num) AS (VALUES(NULL)),
cte AS
...
Case 3
WITH
i(init) AS (VALUES('db2')),
c(cd) AS (VALUES(2018)),
n(num) AS (VALUES(53)),
cte AS
...
However, do be aware the fiddle runs a different SQL due to nature of data (i.e., double and dates). But query does reflect same concept with NVL matching expressions on both sides.
SELECT *
FROM cte, i, c, n
WHERE cte.mytype = NVL(i.init, cte.mytype)
AND YEAR(CAST(cte.mydate AS date)) = NVL(c.cd, YEAR(CAST(cte.mydate AS date)))
AND ROUND(cte.mynum, 0) = NVL(n.num, ROUND(cte.mynum, 0));

SQL MIN() returns multiple values?

I am using SQL server 2005, querying with Web Developer 2010, and the min function appears to be returning more than one value (for each ID returned, see below). Ideally I would like it to just return the one for each ID.
SELECT Production.WorksOrderOperations.WorksOrderNumber,
MIN(Production.WorksOrderOperations.OperationNumber) AS Expr1,
Production.Resources.ResourceCode,
Production.Resources.ResourceDescription,
Production.WorksOrderExcel_ExcelExport_View.PartNumber,
Production.WorksOrderOperations.PlannedQuantity,
Production.WorksOrderOperations.PlannedSetTime,
Production.WorksOrderOperations.PlannedRunTime
FROM Production.WorksOrderOperations
INNER JOIN Production.Resources
ON Production.WorksOrderOperations.ResourceID = Production.Resources.ResourceID
INNER JOIN Production.WorksOrderExcel_ExcelExport_View
ON Production.WorksOrderOperations.WorksOrderNumber = Production.WorksOrderExcel_ExcelExport_View.WorksOrderNumber
WHERE Production.WorksOrderOperations.WorksOrderNumber IN
( SELECT WorksOrderNumber
FROM Production.WorksOrderExcel_ExcelExport_View AS WorksOrderExcel_ExcelExport_View_1
WHERE (WorksOrderSuffixStatus = 'Proposed'))
AND Production.Resources.ResourceCode IN ('1303', '1604')
GROUP BY Production.WorksOrderOperations.WorksOrderNumber,
Production.Resources.ResourceCode,
Production.Resources.ResourceDescription,
Production.WorksOrderExcel_ExcelExport_View.PartNumber,
Production.WorksOrderOperations.PlannedQuantity,
Production.WorksOrderOperations.PlannedSetTime,
Production.WorksOrderOperations.PlannedRunTime
If you can get your head around it, I am selecting certain columns from multiple tables where the WorksOrderNumber is also contained within a subquery, and numerous other conditions.
Result set looks a little like this, have blurred out irrelevant data.
http://i.stack.imgur.com/5UFIp.png (Wouldn't let me embed image).
The highlighted rows are NOT supposed to be there, I cannot explicitly filter them out, as this result set will be updated daily and it is likely to happen with a different record.
I have tried casting and converting the OperationNumber to numerous other data types, varchar type returns '100' instead of the '30'. Also tried searching search engines, no one seems to have the same problem.
I did not structure the tables (they're horribly normalised), and it is not possible to restructure them.
Any ideas appreciated, many thanks.
The MIN function returns the minimum within the group.
If you want the minimum for each ID you need to get group on just ID.
I assume that by "ID" you are referring to Production.WorksOrderOperations.WorksOrderNumber.
You can add this as a "table" in your SQL:
(SELECT Production.WorksOrderOperations.WorksOrderNumber,
MIN(Production.WorksOrderOperations.OperationNumber)
FROM Production.WorksOrderOperations
GROUP BY Production.WorksOrderOperations.WorksOrderNumber)

Convert row data into columns Access 07 without using PIVOT

I am on a work term from school. I am not very comfortable using SQL, I am trying to get a hold of it....
My supervisor gave me a task for a user in which I need to take row data and make columns. We used the Crosstab Wizard and automagically created the SQL to get what we needed.
Basically, we have a table like this:
ReqNumber Year FilledFlag(is a checkbox) FilledBy
1 2012 (notchecked) ITSchoolBoy
1 2012 (checked) GradStudent
1 2012 (notchecked) HighSchooler
2 etc, etc.
What the user would like is to have a listing of all of the req numbers and what is checked
Our automatic pivot code gives us all of the FilledBy options (there are 9 in total) as column headings, and groups it all by reqnumber.
How can you do this without the pivot? I would like to wrap my head around this. Nearest I can find is something like:
SELECT
SUM(IIF(FilledBy = 'ITSchoolboy',1,0) as ITSchoolboy,
SUM(IIF(FilledBy = 'GradStudent',1,0) as GradStudent, etc.
FROM myTable
Could anyone help explain this to me? Point me in the direction of a guide? I've been searching for the better part of a day now, and even though I am a student, I don't think this will be smiled upon for too long. But I would really like to know!
I think your boss' suggestion could work if you GROUP BY ReqNumber.
SELECT
ReqNumber,
SUM(IIF(FilledBy = 'ITSchoolboy',1,0) as ITSchoolboy,
SUM(IIF(FilledBy = 'GradStudent',1,0) as GradStudent,
etc.
FROM myTable
GROUP BY ReqNumber;
A different approach would be to JOIN multiple subqueries. This example pulls in 2 of your categories. If you need to extend it to 9 categories, you would have a whole lot of joining going on.
SELECT
itsb.ReqNumber,
itsb.ITSchoolboy,
grad.GradStudent
FROM
(
SELECT
ReqNumber,
FilledFlag AS ITSchoolboy
FROM myTable
WHERE FilledBy = "ITSchoolboy"
) AS itsb
INNER JOIN
(
SELECT
ReqNumber,
FilledFlag AS GradStudent
FROM myTable
WHERE FilledBy = "GradStudent"
) AS grad
ON itsb.ReqNumber = grad.ReqNumber
Please notice I'm not suggesting you should use this approach. However, since you asked about alternatives to your pivot approach (which works) ... this is one. Stay tuned in case someone else offers a simpler alternative. :-)

SQL - multiple conditions in DCount() function

I am using MS Access 2007.
A: DCount("[Name]","[Main]","[Name] = 'Mark'")/
DCount("[Entry]","[Main]","[Entry] = 1")
Okay, so I am basically counting the number of people with the name Mark and I am dividing it by the number of Entry's that = 1 in my database. That's easy enough, but I am trying to apply a third condition, where
[Location]![City] = 'Chicago'
, but Access isn't letting me do this (It can't find the table, even though it's in the table I specified above.
DCount("[Name]","[Main]","[Name] = 'Mark' AND [Location]![City] = 'Chicago'")/
DCount("[Entry]","[Main]","[Entry] = 1")
I have also tried filtering the city with a Where clause in the Design view, but the condition is being applied after the calculation above, so the calculation is the same regardless of the city. I just need it to perform the above calculation for the city of Chicago.
Is something like this possible with DCount?
Also, I would die a happy man if you could tell me how to Group By the city While performing the calculations for each one separately, but I would also be very thankful if someone could just show me how to do it the first way too.
Thanks
What is [Location]![City]? My answer is based on the presumption it refers to a field named City in a table named Location.
If that is correct, I think your problem is because you're attempting to specify a condition based on a field which is not part of the domain ([Main]) you told DCount to use.
From Microsoft's Documentation, the domain is "A string expression identifying the set of records that constitutes the domain. It can be a table name or a query name for a query that does not require a parameter."
So if you want your DCount criteria to refer to fields in two tables, consolidate the tables in the form of a query into a single "domain". Maybe your query could be something like this, "qryMainWithCity":
SELECT m.[Name], m.Entry, m.City_ID, l.City
FROM
Main AS m
INNER JOIN Location AS l
ON m.City_ID = l.City_ID;
If that query works for your situation, you should be able to get what you want with a DCount expression like this:
DCount("*","qryMainWithCity","[Name] = 'Mark' AND City = 'Chicago'")
I was just posting the same answer as #HansUp's came up. I have an alternative way to do it, and that's to use an instant recordset lookup:
Dim varReturnValue as Variant
varReturnValue = CurrentDB.OpenRecordset("SELECT Main.[Name] FROM Main INNER JOIN Location ON Main.City_ID = Location.City_ID WHERE Main.[Name] = 'Mark' AND Location.City = 'Chicago';")(0)
That returns the first field in the recordset returned (the index is zero-based). That way you don't have to save a query.