How to get multiple to One Relation in Oracle Sql Query - oracle

I have product code defined in a table A where i will list 3 products with quantity. If customer purchase those 3 items I will be offering 1 product free.
Product Code
Item A
Item B
Item C
For these items I will be offering "Item D" as free.
How do I write a query to check, whether all the 3 items are available in current table?

Unfortunately you aren’t giving us enough information to go ahead and help you. From what you said this is what I am thinking. You have a table such as this:
You want a select that checks if all 3 items are available in the current table:
SELECT CASE WHEN COUNT (PRODUCT_CODE) = 3 THEN
'YOU GET FREE ITEM D'
ELSE
'YOU DONT GET ANYTHING'
END AS ANSWER
FROM TABLE_A
WHERE (PRODUCT_CODE = PRODUCT_CODE_1 AND QUANTITY > 0)
OR (PRODUCT_CODE = PRODUCT_CODE_2 AND QUANTITY > 0)
OR (PRODUCT_CODE = PRODUCT_CODE_3 AND QUANTITY > 0)
So basically the where clause is check if those 3 items exists and there quantity is greater than zero. Then I wrote a Case statement (you can use decode if you prefer) to check if the count is 3 then give me my free item else don’t give me.

Related

I need to perform subtraction and a filter in the same column that I create in Power BI

enter image description here
I need to create a column which subtracts [Retailer_yes_amount] and [classification_base_amount] and at the same time filter out "Not Eligible" category in [Classification] column. [Classification] column has 5 categories - Platinum, Gold, Silver, Bronze and Not eligible.
I was thinking like this New_column = calculate(([Retailer_yes_amount]-[classification_base_amount]),filter('table_name',[classification] <> "Not Eligible")) but it threw an error.
Kindly suggest
If you want to have this evaluated for every row as a new column you have to enter the following expression as a Calculated Column
New_column =
IF(
table_name[Classification] <> "Not Eligible",
[Retailer_yes_amount] - [classification_base_amount]
)
If you want to use a measure you have to specify an aggregation.

List.Distinct and List.Count Challenge

Within PQ, I have a table of data (below) to which I am trying to determine whether all the columns titled Plan Status-# are the same, excluding blanks, and if all the same, display that value and if not display "Varies across plans"
The PQ code is below where I use List.Distinct to create a list of all "unique values".
I then use List.Count to count this number in the list and if 1, set the column equal to the Distinct value.
If List.Count({List.Distinct({[#"Plan Status-H"],[#"Plan Status-D"],[#"Plan Status-S"],[#"Plan Status-M"],[#"Plan Status-C"],[#"Plan Status-U"]})})=1 then List.Distinct({[#"Plan Status-H"],[#"Plan Status-D"],[#"Plan Status-S"],[#"Plan Status-M"],[#"Plan Status-C"],[#"Plan Status-U"]}) else "Varies across plans"
As per the table above, the List.Count does not seem to working correctly as some of the records show a merged value of items in the list which means the List.Count for a list with multiple values is calcing as 1.
You have extra brackets in your code. Try this:
if List.Count(List.Distinct({[#"Plan Status-H"],[#"Plan Status-D"],[#"Plan Status-S"],[#"Plan Status-M"],[#"Plan Status-C"],[#"Plan Status-U"]}))=1
then List.Distinct({[#"Plan Status-H"],[#"Plan Status-D"],[#"Plan Status-S"],[#"Plan Status-M"],[#"Plan Status-C"],[#"Plan Status-U"]})
else "Varies across plans"

How does a multi-column index work in oracle?

I'm building a table to manage some articles:
Table
| Company | Store | Sku | ..OtherColumns.. |
| 1 | 1 | 123 | .. |
| 1 | 2 | 345 | .. |
| 3 | 1 | 123 | .. |
Scenario
Most time company, store and sku will be used to SELECT rows:
SELECT * FROM stock s WHERE s.company = 1 AND s.store = 1 AND s.sku = 123;
..but sometimes the company will not be available when accessing the table.
SELECT * FROM stock s WHERE s.store = 1 AND s.sku = 123;
..Sometimes all articles will be selected for a store.
SELECT * FROM stock s WHERE s.company = 1 AND s.store = 1;
The Question
How to properly index the table?
I could add three indexes - one for each select, but i think oracle should be smart eneugh to re-use other indexes.
Would an Index "Store, Sku, Company" be used if the WHERE-condition has no company?
Would an Index "Company, Store, Sku" be used if the WHERE-condition has no company?
You can think of the index key as conceptually being the 'concatenation' of the all of the columns, and generally you need to have a leading element of that key in order to get benefit from the index. So for an index on (company,store,sku) then
WHERE s.company = 1 AND s.store = 1 AND s.sku = 123;
can potentially benefit from the index
WHERE s.store = 1 AND s.sku = 123;
is unlikely to benefit (but see footnote below)
WHERE s.company = 1 AND s.store = 1;
can potentially benefit from the index.
In all cases, I say "potentially" etc, because it is a costing decision by the optimizer. For example, if I only have (say) 2 companies and 2 stores then a query on company and store, whilst it could use the index is perhaps better suited to not to do so, because the volume of information to be queried is still a large percentage of the size of the table.
In your example, it might be the case that an index on (store,sku,company) would be "good enough" to satisfy all three, but that depends on the distribution of data. But you're thinking the right way, ie, get as much value from as few indexes as possible.
Footnote: There is a thing called a "skip scan" where we can get value from an index even if you do not specify the leading column(s), but you will typically only see that if the number of distinct values in those leading columns is low.
first - do you need index at all? Indexes are not for free. If your table is small enoguh, perhaps you don't need index at all.
Second - what is data structure? You have store column in every scenario - I can imagine situation in which filtering data on store dissects source data to enough degree to be good enough for you.
However if you want to have maximum reasonable performance benefit you need two:
(store, sku, company)
(store, company)
or
(store, company, sku)
(store, sku)
Would an Index "Store, Sku, Company" be used if the WHERE-condition has no company?
Yes
Would an Index "Company, Store, Sku" be used if the WHERE-condition has no company?
Probably not, but I can imagine scenarios in which it might happen (not for the index seek operation which is really primary purpose of indices)
You dissect data in order of columns. So you group data by first element and order them by first columns sorting order, then within these group you group the same way by second element etc.
So when you don't use first element of index in filtering, the DB would have to access all "subgroups" anyway.
I recommend reading about indexes in general. Start with https://en.wikipedia.org/wiki/B-tree and try to draw how it behaves on paper or write simple program to manage simplified version. Then read on indexes in database - any db would be good enough.

Linq Query Where Contains

I'm attempting to make a linq where contains query quicker.
The data set contains 256,999 clients. The Ids is just a simple list of GUID'S and this would could only contain 3 records.
The below query can take up to a min to return the 3 records. This is because the logic will go through the 256,999 record to see if any of the 256,999 records are within the List of 3 records.
returnItems = context.ExecuteQuery<DataClass.SelectClientsGridView>(sql).Where(x => ids.Contains(x.ClientId)).ToList();
I would like to and get the query to check if the three records are within the pot of 256,999. So in a way this should be much quicker.
I don't want to do a loop as the 3 records could be far more (thousands). The more loops the more hits to the db.
I don't want to grap all the db records (256,999) and then do the query as it would take nearly the same amount of time.
If I grap just the Ids for all the 256,999 from the DB it would take a second. This is where the Ids come from. (A filtered, small and simple list)
Any Ideas?
Thanks
You've said "I don't want to grab all the db records (256,999) and then do the query as it would take nearly the same amount of time," but also "If I grab just the Ids for all the 256,999 from the DB it would take a second." So does this really take "just as long"?
returnItems = context.ExecuteQuery<DataClass.SelectClientsGridView>(sql).Select(x => x.ClientId).ToList().Where(x => ids.Contains(x)).ToList();
Unfortunately, even if this is fast, it's not an answer, as you'll still need effectively the original query to actually extract the full records for the Ids matched :-(
So, adding an index is likely your best option.
The reason the Id query is quicker is due to one field being returned and its only a single table query.
The main query contains sub queries (below). So I get the Ids from a quick and easy query, then use the Ids to get the more details information.
SELECT Clients.Id as ClientId, Clients.ClientRef as ClientRef, Clients.Title + ' ' + Clients.Forename + ' ' + Clients.Surname as FullName,
[Address1] ,[Address2],[Address3],[Town],[County],[Postcode],
Clients.Consent AS Consent,
CONVERT(nvarchar(10), Clients.Dob, 103) as FormatedDOB,
CASE WHEN Clients.IsMale = 1 THEN 'Male' WHEN Clients.IsMale = 0 THEN 'Female' END As Gender,
Convert(nvarchar(10), Max(Assessments.TestDate),103) as LastVisit, ";
CASE WHEN Max(Convert(integer,Assessments.Submitted)) = 1 Then 'true' ELSE 'false' END AS Submitted,
CASE WHEN Max(Convert(integer,Assessments.GPSubmit)) = 1 Then 'true' ELSE 'false' END AS GPSubmit,
CASE WHEN Max(Convert(integer,Assessments.QualForPay)) = 1 Then 'true' ELSE 'false' END AS QualForPay,
Clients.UserIds AS LinkedUsers
FROM Clients
Left JOIN Assessments ON Clients.Id = Assessments.ClientId
Left JOIN Layouts ON Layouts.Id = Assessments.LayoutId
GROUP BY Clients.Id, Clients.ClientRef, Clients.Title, Clients.Forename, Clients.Surname, [Address1] ,[Address2],[Address3],[Town],[County],[Postcode],Clients.Consent, Clients.Dob, Clients.IsMale,Clients.UserIds";//,Layouts.LayoutName, Layouts.SubmissionProcess
ORDER BY ClientRef
I was hoping there was an easier way to do the Contain element. As the pool of Ids would be smaller than the main pool.
A way I've speeded it up for now is. I've done a Stinrg.Join to the list of Ids and added them as a WHERE within the main SQL. This has reduced the time down to a seconds or so now.

SQL/SSRS Nested Query where, IN and AND

I want to get events in one the 3 types and for 1 type only where quantity is greater than 0. However, quantity is 0 for other two types and I want them as well in output.
Query I am using - WHERE
({PortfolioEvent.EventType} IN ("Call","Mature", "Sell")) OR (({PortfolioEvent.EventType} == "Sell" AND QtyAmount >=1))
I want transactions at call and mature level in output regardless of quantity of 0.
Thanks

Resources