I need to run a query that pulls client machine information into PowerBI from SQL Server based on required and non required parameters.
I have the parameters set up but am unable to get my SQL code to work. My two parameters are SelectClient1 and SelectClient2. Some clients have multiple names and usually an acronym abbreviation such as Joe's Construction, Joe's Construction LLC, and JCLLC. I need to be able to bring back all those names.
SELECT *
FROM table1, table2
WHERE table1.InspectionId = table2.InspectionId
AND OwnerName like '%"&SelectClient1&"%'
OR OwnerName like '%"&SelectClient2&"%'
My issue with the code above is sometimes I will leave SelectClient2 blank. In this case I would need the code to work and only bring back where owner is like SelectClient1.
Return something like this...
InspectionID Client Machine Severity
1 "Joe's Construction LLC" A High
2 "Joe's Construction LLC" B Low
3 "Joe's Construction" A Low
4 "JCLLC" A Medium
5 "JCLLC" B Medium
You are struggling here because you don't have any parenthesis around your predicates. If you used "modern" join structure this wouldn't matter in your query. Here is what your query would look like using ANSI-92 style joins and parameters. Please note that when you have a leading wildcard in a predicate like this you have rendered the query nonSARGable and no indexing is going to help.
SELECT *
FROM table1
join table2 on table1.InspectionId = table2.InspectionId
WHERE OwnerName like '%' + #SelectClient1 + '%'
OR OwnerName like '%' + #SelectClient2 + '%'
Related
I am trying to pull a report of all the documents referenced in AX, and I'm having a heck of a time figuring out the AX database structure. Ideally I want to pull a list of documents and the Journal / Batch # each is associated with.
In our AX environment, all documents are stored on a share (i.e. they're not actually stored as BLOBs in the AX database).
It looks like the DOCUVALUE table is the principal table that references the documents, having the ORIGINALFILENAME and other columns that seem to "point" to the files on the AX share. But DOCUVALUE doesn't contain any useful business metadata.
After a bit of exploring, it looks like like the DOCUREF table relates to DOCUVALUE (DOCUVALUE.RECID = DOCUREF.VALUERECID) which helps a little - gives you the Company #, but that's about it.
After a bit more exploring, it looked like it would be possible to join across to LEDGERJOURNALTABLE as shown below:
select ljt.journalnum, filename + '.' + filetype filename, ljt.name journal_name,
dr.refcompanyid, convert(varchar(10), ljt.posteddatetime,111) posted_date,
ljt.createdby, convert(numeric, ljt.journaltotalcredit) journalamount
from LEDGERJOURNALTABLE ljt, DOCUREF dr, DOCUVALUE dv
where dv.RECID = dr.VALUERECID and dr.refrecid = ljt.recid
order by 1,2
This looked promising, so I pulled out a data listing and asked one of our key business users to review the results. She indicated that it was accurate to some extent, but there were other areas where the document referenced just didn't have any relation to the JournalNum in the listing.
So - I'm at a bit of a dead end - I've spent further time generating SQL statements to harvest data using specific RECID values, trying other joins, but each time I just disappear down a rabbit hole.
Any ideas? Any help gratefully received!!
The AX document management framework is designed so that a document can be attached to any data row in any table. What you're trying to do is far easier in AX, but we'll stick with SQL for the question.
The problem you're having is you don't know the reference objects because you're ignoring REFTABLEID.
The key fields that connect a denormalized "document" to the associated business data are REFTABLEID, REFCOMPANYID, and REFRECID (you already have the last one).
So start with this query below:
SELECT sd.NAME
,sd.SQLNAME
,dr.*
,dv.*
FROM DOCUREF dr
,DOCUVALUE dv
,SQLDICTIONARY sd
WHERE dv.RECID = dr.VALUERECID
AND sd.TABLEID = dr.REFTABLEID
AND sd.FIELDID = 0 -- Indicates it is a table and not a table field
AND sd.NAME = 'LEDGERJOURNALTABLE' -- Instead of hardcoding, join & query
You'll have to get creative depending on your use with SQL, You'll want to remove the hardcoded 'LEDGERJOURNALTABLE' and then use sd.SQLNAME to join to the actual SQL table. Then if that SQL table has DataAreaId, you'd likely want to join it to dr.REFCOMPANYID.
Or you can hardcode the tables or whatever you want to do. You should be aware you can attach documents to journal headers OR lines...or many other rows for that matter.
Just start exploring the data and you should be able to figure out what you want with that query above.
So for your sample query, you can see I added 2 lines. Your query will only work when joined for LedgerJournalTable. You'll have to do some dynamic SQL or use a cursor or something if you want to report on every attachment.
SELECT ljt.journalnum
,filename + '.' + filetype filename
,ljt.name journal_name
,dr.refcompanyid
,convert(VARCHAR(10), ljt.posteddatetime, 111) posted_date
,ljt.createdby
,convert(NUMERIC, ljt.journaltotalcredit) journalamount
FROM LEDGERJOURNALTABLE ljt
,DOCUREF dr
,DOCUVALUE dv
WHERE dv.RECID = dr.VALUERECID
AND dr.REFRECID = ljt.RECID
AND dr.REFCOMPANYID = ljt.DATAAREAID -- ADDED
AND dr.REFTABLEID = 211 -- ADDED TableId for LedgerJournalTable
ORDER BY 1
,2
So, I have Hibernate 5.3.1 in a project which connects to different enginees (MySql, Oracle, PostgreSQL and MS SQL), so I can't use native queries.
Let's say I have 3 records in a table, which all of them have the same datetime, but I need to group them only by date (not time). For example, 2019-12-04;
I execute this query:
SELECT
CONCAT(year(tx.date_), month(tx.date_), day(tx.date_)),
iss.code,
COUNT(tx.id)
FROM
tx_ tx
JOIN
issuer_ iss
ON
tx.id_issuer = iss.id
GROUP BY
CONCAT(year(tx.date_), month(tx.date_), day(tx.date_)), iss.code
But, when I test it connected to SQL SERVER 2017, instead of return 20191204, it's returning 2035. In Oracle and MySQL is working fine.
Anyone has any idea why is this happen? I've tried different ways, like use + instead of CONCAT but the result is the same.
I've also tried to extract them for separate (without concat), and they have been returning correct. The problem is, I need to group them by the complete date.
And just for the record, the field is declared as datetime2 in DDBB
How about simply adding them, instead of using CONCAT.
(year(tx.date_)*10000 + month(tx.date_)*100 + day(tx.date_)*1) AS datenum
Thus, try this:
SELECT
CAST((year(tx.date_)*10000 + month(tx.date_)*100 + day(tx.date_)*1) AS string) AS datenum,
iss.code
FROM tx_ tx
JOIN issuer_ iss
ON tx.id_issuer = iss.id
GROUP BY year(tx.date_), month(tx.date_), day(tx.date_), iss.code
Thanks for the hint Gert Arnold gave me. I just didn't realize that the query was adding like if they were numbers in MSSQL.
Finally, I manage to make it work in the 4 RDBMS casting to string first
SELECT
CONCAT(CAST(year(tx.date_) AS string), CAST(month(tx.date_) AS string), CAST(day(tx.date_) AS string)),
iss.code
FROM
tx_ tx
JOIN
issuer_ iss
ON
tx.id_issuer = iss.id
GROUP BY
CONCAT(year(tx.date_), month(tx.date_), day(tx.date_)), iss.code
I tried also casting to TEXT, but it throws exception in MySQL
Why use concat() to begin with?
Assuming Hibernate takes care of converting the non-standard year(), month() and day() functions, then the following should work on any DBMS
SELECT year(tx.date_), month(tx.date_), day(tx.date_), iss.code
FROM tx_ tx
JOIN issuer_ iss ON tx.id_issuer = iss.id
GROUP BY year(tx.date_), month(tx.date_), day(tx.date_), iss.code
I'm trying to pass a string parameter obtained by another query to another query in the same dashboard but when I use the parameter no results was selected. What is the proper syntax or where is the problem.
I'm beginner in pentaho biserver-CE. I use version 6.1. with JDBC connection to SQL Server 2016 SP1.
Now I'm making a sales dashboard from invoices and i want to make a dynamic filter by the time units (which works fine) and by the country shortcuts (which didn't work). If i pass shortcut of some country directly with quotes it works fine but when I replace it by the parameter it doesn't select nothing (Also in CDA preview). When I made some reports in Jasper i used exclamation inside of the parameter to pass quoted value but here I didn't find anything like this for Pentaho.
select top 10
invrow.item as ITEM,
invrow.agent as AGENT,
sum(invrow.qt) as MEASURE,
sum(invrow.val) as VALUE
from invrow
left join invhead on invrow.type = invhead.type
and invrow.nr = invhead.nr
left join art on invrow.item = art.item
where left(invhead.date,4) = ${year}
and invhead.country like ${Country}
group by invrow.item, invrow.agent, invhead.country
order by MEASURE DESC
parameter ${Country} was acquired by another query by the same field. There is a query to gain the parameter:
select distinct
invhead.country
from
invhead
where
left(invhead.date,4) = ${year}
The original query shows nothing but when I Replace parameter ${Country} by for example 'UK' like this.
It works fine:
select top 10
invrow.item as ITEM,
invrow.agent as AGENT,
sum(invrow.qt) as MEASURE,
sum(invrow.val) as VALUE
from invrow
left join invhead on invrow.type = invhead.type
and invrow.nr = invhead.nr
left join art on invrow.item = art.item
where left(invhead.date,4) = ${year}
and invhead.country like 'UK'
group by invrow.item, invrow.agent, invhead.country
order by MEASURE DESC
Now when I use parameter I have nothing in the select list but there are rows, which should be selected.
The syntax is correct, but that way of passing parameters only works for single valued parameters.
To pass an array of parameters, as you seem to be trying, you need to pass the parameter as right hand side of a in operator,
(...)
and invhead.country in ( ${Country} )
(...)
and set the parameter to be of type StringArray.
I am new to SQL and it seems not to be the same as tradition coding. Anyways, I am trying to figure out why my results end up empty but only with the first AND statement. If I remove this statement, the code works. The syntax seems correct. What I am trying to do is match channel names with 'P' and 'HDP' at the end of the columns and not match channel numbers. Maybe I am wrong on the syntax. Any help on this matter would be appreciated. Also, I am using Microsoft SQL Server Management Studio 2012.
How the results should look:
SELECT a.ChannelNumber AS "Standard Channel",
a.DisplayName AS "Standard Name",
b.ChannelNumber AS "HD Channel",
b.DisplayName AS "HD Name"
FROM CHANNEL a CROSS JOIN CHANNEL b
WHERE b.ChannelNumber <> a.ChannelNumber
AND b.DisplayName = a.DisplayName /*this is what is giving me problems*/
AND RIGHT(b.DisplayName, 3) LIKE '%HDP'
AND RIGHT(a.DisplayName, 1) LIKE '%P';
Ultimately you want things like AETVP and AETVHDP to be "equal". This doesn't seem like a use case for a Cross Join. You can break this down with a CTE.
First you'll define your HD channels, then your Standard Channels. In each of those blocks you can get the core part of the channel's name (the part without the P or HDP). Then join those together on the CoreName. This will enable us to join AETV to AETV
WITH HdChannels
AS (
SELECT *
,CoreName = left(DisplayName, len(DisplayName) - len('HDP'))
FROM Channel
WHERE displayName LIKE '%HDP'
)
,StdChannels
AS (
SELECT *
,CoreName = left(DisplayName, len(DisplayName) - len('P'))
FROM Channel
WHERE displayName LIKE '%P'
AND displayName NOT LIKE '%HDP'
)
SELECT std.ChannelNumber AS [Standard Channel]
,std.DisplayName AS [Standard Name]
,hd.ChannelNumber AS [HD Channel]
,hd.DisplayName AS [HD Name]
FROM HdChannels hd
INNER JOIN StdChannels std ON std.CoreName = hd.CoreName
To answer your question,
"Give reasons as to why my AND clause returns an empty string in SQL"
it's because you've declared a.DisplayName = b.DisplayName in the WHERE. And that can't be the case according to the picture of the output you've linked to because the Display names are spelled differently.
The only difference between standard and HD tables is HD tables end with "HDP". Standard tables never end with "HDP", though they do end with a "P".
In the absence of sample data, I've included the most basic example I could think of using a temp table.
DECLARE #CHANNEL TABLE(ChannelNumber int, DisplayName varchar(100))
INSERT INTO #CHANNEL VALUES
(3, 'ABCP'), (25, 'ABCHDP')
SELECT a.ChannelNumber AS "Standard Channel",
a.DisplayName AS "Standard Name",
b.ChannelNumber AS "HD Channel",
b.DisplayName AS "HD Name"
FROM #CHANNEL a CROSS JOIN #CHANNEL b
WHERE LEFT(a.DisplayName, LEN(a.DisplayName) - 1) + 'HDP' = b.DisplayName
AND a.DisplayName NOT LIKE '%HDP'
AND b.DisplayName LIKE '%HDP'
AND a.ChannelNumber <> b.ChannelNumber
Produces output:
Standard Channel Standard Name HD Channel HD Name
3 ABCP 25 ABCHDP
The algorithm identifies standard channels (NOT LIKE '%HDP') and HD channels (LIKE '%HDP') on the left and right sides of the CROSS JOIN.
Notice in your code you put: AND RIGHT(b.DisplayName, 3) LIKE '%HDP'... it is unnecessary to specify the RIGHT function with a length of chars- when you indicate the end of the string using LIKE '%HDP'.
LEFT(a.DisplayName, LEN(a.DisplayName) - 1) + 'HDP' cuts off the last char of the Standard Channel's DisplayName (which is always a 'P' by it's naming convention) and concatenates 'HDP' at the end of the result. This is compared to the format for HD channels which always end with 'HDP'.
When the conditions match you get a row of data.
Looking at the filtering conditions- you can see that a.DisplayName can never equal b.DisplayName
SQL - How can I return a value from a different table base on a parameter
First time poster, long time reader:
I am using a custom Excel function that allows be to pass parameters and build a SQL string that returns a value. This is working fine. However, I would like to choose among various tables based on the parameters that are passed.
At the moment I have two working functions with SQL statements look like this:
_______FUNCTION ONE________
<SQLText>
SELECT PRODDTA.TABLE1.T1DESC as DESCRIPTION
FROM PRODDTA.TABLE1
WHERE PRODDTA.TABLE1.T1KEY = '&PARM02'</SQLText>
_______FUNCTION TWO________
<SQLText>
SELECT PRODDTA.TABLE2.T2DESC as DESCRIPTION
FROM PRODDTA.TABLE2
WHERE PRODDTA.TABLE2.T2KEY = '&PARM02'</SQLText>
So I am using IF logic in Excel to check the first parameter and decide which function to use.
It would be much better if I could do a single SQL statement that could pick the right table based on the 1st parameter. Logically something like this:
_______FUNCTIONS COMBINED________
IF '&PARM02' = “A” THEN
SELECT PRODDTA.TABLE1.T1DESC as DESCRIPTION
FROM PRODDTA.TABLE1
WHERE PRODDTA.TABLE1.T1KEY = '&PARM02'
ELSE IF '&PARM02' = “B” THEN
SELECT PRODDTA.TABLE2.T2DESC as DESCRIPTION
FROM PRODDTA.TABLE2
WHERE PRODDTA.TABLE2.T2KEY = '&PARM02'
ELSE
DESCRIPTION = “”
Based on another post Querying different table based on a parameter I tried this exact syntax with no success
<SQLText>
IF'&PARM02'= "A"
BEGIN
SELECT PRODDTA.F0101.ABALPH as DESCRIPTION
FROM PRODDTA.F0101
WHERE PRODDTA.F0101.ABAN8 = '&PARM02'
END ELSE
BEGIN
SELECT PRODDTA.F4801.WADL01 as DESCRIPTION
FROM PRODDTA.F4801
WHERE PRODDTA.F4801.WADOCO = '&PARM02'
END</SQLText>
You could try using a JOIN statement.
http://www.sqlfiddle.com/#!9/23461d/1
Here is a fiddle showing two tables.
The following code snip will give you the values from both tables, using the Key as the matching logic.
SELECT Table1.description, Table1.key, Table2.description
from Table1
Join Table2 on Table1.key = Table2.key
Here's one way to do it. If PARM03='Use Table1' then the top half of the union will return records and vice versa. This won't necessarily product good performance though. You should consider why you are storing data in this way. It looks like you are partitioning data across different tables which is a bad idea.
SELECT PRODDTA.TABLE1.T1DESC as DESCRIPTION
FROM PRODDTA.TABLE1
WHERE PRODDTA.TABLE1.T1KEY = '&PARM02'
AND &PARM03='Use Table1'
UNION ALL
SELECT PRODDTA.TABLE2.T2DESC as DESCRIPTION
FROM PRODDTA.TABLE2
WHERE PRODDTA.TABLE2.T2KEY = '&PARM02'</SQLText>
AND &PARM03='Use Table2'