Sql Query for Commissions (Decision?) Table - sql

SQL 2008
I have a commission table that looks like this:
Comm% | ProfitStartRange | ProfitEndRange
0.01 | 0.00 | 100.99
0.02 | 101 | 500.99
0.03 | 501 | 1000.99
etc...
Basically I want create a query that returns the appropriate Comm% based on a value. I would like to do this inline and not in a user defined function if possible as I will be calculating a large set.

SELECT comm from yourtable
where profit BETWEEN yourtable.ProfitStartRange and yourtable.ProfitEndRange

Related

Conditionally Relate New Tables

I run a store that sells cigarettes, which have certain promotions given to us by the manufacturer that effect their pricing. These promotions are organized into groups of products (like all menthol or all reds) and are subject to frequent change, making them a bear to manage. My end goal here is to create a table(s) that will help me track these promotions and run an UPDATE query that will adjust their prices.
I have table inventory like
itemnum|dept_id|cost |price
-----------------------------
123 | cig | 2.6 | 3.4
234 | 401 | 2.22| 23.4
345 | cig | 3.33| 3.45
456 | cig | 4.00| 4.56
567 | 901 | 4.5 | 5.67
678 | cig | 4.1 | 6.25
789 | cig | 5.2 | 6.25
My initial thought was creating a set of new tables like
CigGroup
Brand | Group_id | Itemnum
-------------------------------
Altria| a_men | 123
Altria| a_men | 345
Altria| a_black | 456
RJR | r_crush | 678
RJR | r_crush | 789
And
CigGroup_Promo
Group_id |promo_1|promo_2|promo_n...|net_promo|
--------------------------------------------
a_men | .5 | 1 | .1 | 1.6 (promo_1 + ...promo_n...)
a_red | .25 | 1 | NULL | 1.25
a_black | .25 | .5 | .1 | .85
r_crush | .25 | .1 | NULL | .35
r_filter | .35 | .5 | NULL | .85
I thought that maybe I could do something conditionally with foreign keys and set Cig_Group.Itemnum to reference inventory.itemnum only when inventory.itemnum = 'cig', though from SQL Server Conditional Foreign Key
I gathered that this might not be possible. (I've also looked into composite keys, but not sure how to apply this to my data)
So, here are my questions:
First, is it possible to populate my new table(s) (however that ends up being structured) with inventory.itemnum only when inventory.dept_id = 'cig' ?
Second, can i set CigGroup_Promo.Net_Promo as a function of promo_1, promo_2, promo_n..., or is that yet another table that I would be creating?
Any suggestions on how to structure tables for these data and how to relate them would be greatly appreciated.
Side note: I could, instead of creating CigGroup, create new values for inventory.dept_id, which I would honestly prefer not to do, but might make things simpler.
Once all the tables are created and related, I'm hoping to be able to run something like:
UPDATE inventory i SET price =
CASE WHEN 1.07 * (i.cost - g.net_promo) >= .5 + (i.cost - g.net_promo)
THEN 1.07 * (i.cost - g.net_promo)
ELSE .5 + (i.cost - g.net_promo)
END
FROM inventory i JOIN GigGroup g ON i.itemnum = g.itemnum
JOIN CigGroup_Promo p ON g.group_id = p.group_id
Looks to me like there are multiple solutions for design available that would depend on how the source data is loaded and whether you require to track all periodic changes (in which case your model will need datetime-support).
There may be a variety of options, but I would explore a Star Schema design which would entail building your wide and descriptive dimension tables to link with a PKey - FKey relationship to a central Fact table that records all your transactions (in your case that would be the various "promotion" prices that need to be tracked).
In your example based on my comprehension i would opt for a star schema design with dimensions for item, brandGroup and any other required dimensions along with a fact table for tracking inventory and another fact table for tracking price updates. By designing the tables to a conformed dimensional model we can do all types of analysis across this new warehouse.
With regards to your "CigGroup"table specifically, I would create a table for "Items" with the most granular SKU / item on sale, which can then be structured into a hierarchy using attributes, or new columns in the table.

flip a table sql server with dynamic columns and fix rows

after a lot of join and group by i have come to the totals that i wanted...
to keep things simples i will reduce the complexity of the table..
lets say that i have this table that give me the totals of models per year/mont
YearMonth| Totals|model
------------------------
2015-05 | 70 |AA
2015-05 | 50 |BB
2015-06 | 30 |AA
2015-06 | 10 |BB
------------------
201x-yy | 33 |AA
201x-yy | 90 |BB
i have to create a specific (non convencional)graphic in excel with this data
but the only way is to transform the table to something
where the columns are dynamic and the rows fix... something like this
Model|2015-05|2015-06|----|201X-yy
------------------------------------
AA | 70 | 30 |--- |33
BB | 50 | 10 |----|90
is it possible to create with a query? or do i have to do it use some complex store procedure to first create a temp table and than insert data into it.
Me recommendation in this case is to return that data into Excel, and use Excel pivot table to get your output. You can tell Excel to return a linked quiet directly to a pivot table.

How to get subtotals with time datatype in SQL?

I get stuck generating a SQL query. I have a Table in a Firebird DB like the following one:
ID | PROCESS | STEP | TIME
654 | 1 | 1 | 09:08:40
655 | 1 | 2 | 09:09:32
656 | 1 | 3 | 09:10:04
...
670 | 2 | 15 | 09:30:05
671 | 2 | 16 | 09:31:00
and so on.
I need the subtotals for each process group (It's about 7 of these). The table has the "time"-type for the TIME column.I have been trying it with DATEDIFF, but it doesn't work.
You need to use SUM
This question has been answered here.
How to sum up time field in SQL Server
and here.
SUM total time in SQL Server
For more specific Firebird documentation. Read up on the sum function here.
Sum() - Firebird Official Documentation
I think you should use "GROUP BY" to get max time and min time, and to use them in the datediff function. Something like that:
select process, datediff(second, max(time), min(time)) as nb_seconds
from your_table
group by process;

Sql query to return missing rows as NaN from Where IN clause, using matlab odbc

I have an ms access database with table DATA as follows
DATE | SYMBOL | CLOSE |
01/01/99 ABC 10.00
01/02/99 ABC 13.00
01/07/99 ABC 20.00
01/12/99 ABC 22.00
01/30/99 ABC 39.00
01/01/99 XYZ 11.00
01/02/99 XYZ 14.00
01/07/99 XYZ 17.00
01/12/99 XYZ 19.00
01/30/99 XYZ 21.20
And using matlab I would like to select all close values for which their corresponding dates match my 'dates of interest' for a given symbol, so I use an query as follows:
sqlquery = ['select CLOSE from DATA where DATE in (' dates ') and SYMBOL = 'ABC'];
where
dates = '#01/01/99#,#01/02/99#,#01/03/99#,#01/04/99#,#01/05/99#,#01/06/99#,#01/07/99#';
The issue I am facing is such that if I am asking for a CLOSE value corresponding to a query date which does not exist as a record for the given symbol, I would like to receive a null value for CLOSE where a record is missing (the current query does not do this). Ultimately in my program I would like to take the response from my query and copy it into an array for the symbol as follows:
01/01/99 | 10.00 |
01/02/99 | 13.00 |
01/03/99 | NaN |
01/04/99 | NaN |
01/05/99 | NaN |
01/06/99 | NaN |
01/07/99 | 20.00 |
Is there a way to accomplish this response data via an sql query?
You need to provide the date range you are searching for before you can find if there are empty rows or not.
very similar question and answers can be found here:
https://stackoverflow.com/a/39791046/1684486

Oracle, Mysql, how to get average

How to get Average fuel consumption only using MySQL or Oracle:
SELECT te.fuelName,
zkd.fuelCapacity,
zkd.odometer
FROM ZakupKartyDrogowej zkd
JOIN TypElementu te
ON te.typElementu_Id = zkd.typElementu_Id
AND te.idFirmy = zkd.idFirmy
AND te.typElementu_Id IN (3,4,5)
WHERE zkd.idFirmy = 1054
AND zkd.kartaDrogowa_Id = 42
AND zkd.data BETWEEN to_date('2015-09-01','YYYY-MM-DD')
AND to_date('2015-09-30','YYYY-MM-DD');
Result of this query is:
fuelName | fuelCapacity | odometer | tanking
-------------------------------------------------
'ON' | 534 | 1284172 | 2015-09-29
'ON' | 571 | 1276284 | 2015-09-02
'ON' | 470 | 1277715 | 2015-09-07
'ON' | 580.01 | 1279700 | 2015-09-11
'ON' | 490 | 1281103 | 2015-09-17
'ON' | 520 | 1282690 | 2015-09-23
We can do it later in java or php, but want to get result right away from query. How should we modify above query to do that?
fuelCapacity is the number of liters of fuel that has been poured into cartank at gas station.
For one total average, what you need is the sum of the refills divided by the difference between the odometer readings at the start and the end, i.e. fuel used / distance travelled.
I don't have your table structure at hand, but this alteration to the select statement should do the trick:
select cast(sum(zkd.fuelCapacity) as float) / (max(zkd.odometer) - min(zkd.odometer)) as consumption ...
The cast(field AS float) does what the name implies, and typecasts the field as float, so the result will also be a float. (I do suspect that your fuelCapacity field is a float because there is one float value in your example, but this will make sure.)