[Resolved - see update]
I have this L2S query (looks scary, but the bit that's going wrong is simple):
var historicDataPointValues = from dpv in this._dataContext.DataPointValues
where (dpv.categoryId == historicCategoryId)
&& (dpv.retailerId == historicRetailerId)
&& (dpv.questionId == question.PreviousQuestionId)
&& historicResponseIds.Contains(dpv.responseIndex)
&& ((dpv.dataPointIndex == firstDataPointIndex) || (dpv.dataPointIndex == secondDataPointIndex))
select new KeyValuePair<string, double>(MakeDataPointValueKey(dpv), dpv.value);
...which was producing no results, so I looked at the SQL emitted by L2S.
When I execute it, the value of firstDataPointIndex is 1 and secondDataPointIndex is null. Yet the query that L2S produces (as shown in the debugger) is:
SELECT [t0].[categoryId], [t0].[retailerId], [t0].[questionId], [t0].[responseIndex], [t0].[dataPointIndex], [t0].[value]
FROM [dbo].[DataPointValue] AS [t0]
WHERE ([t0].[categoryId] = 1)
AND ([t0].[retailerId] = 1)
AND (([t0].[questionId]) = 8)
AND ([t0].[responseIndex] IN (1, 3, 4, 5, 6, 7, 8, 10, 11, 12))
AND (([t0].[dataPointIndex] = 13) OR ((CONVERT(Int,[t0].[dataPointIndex])) = 14))
Note the values 13 & 14 where firstDataPointIndex and secondDataPointIndex should be (they should be 1 and NULL; if I put in the correct values, then I get the results I expect).
WTF?
UPDATE: Turns out that the L2S debugger was at fault. It wasn't showing the same SQL as what's actually sent to the server, which is:
exec sp_executesql N'SELECT [t0].[categoryId], [t0].[retailerId], [t0].[questionId], [t0].[responseIndex], [t0].[dataPointIndex], [t0].[value]
FROM [dbo].[DataPointValue] AS [t0]
WHERE ([t0].[categoryId] = #p0) AND ([t0].[retailerId] = #p1) AND (([t0].[questionId]) = #p2) AND ([t0].[responseIndex] IN (#p3, #p4, #p5, #p6, #p7, #p8, #p9, #p10, #p11, #p12)) AND (([t0].[dataPointIndex] = #p13) OR ((CONVERT(Int,[t0].[dataPointIndex])) = #p14))',N'#p0 int,#p1 int,#p2 int,#p3 int,#p4 int,#p5 int,#p6 int,#p7 int,#p8 int,#p9 int,#p10 int,#p11 int,#p12 int,#p13 int,#p14 int',#p0=1,#p1=1,#p2=8,#p3=1,#p4=3,#p5=4,#p6=5,#p7=6,#p8=7,#p9=8,#p10=9,#p11=10,#p12=11,#p13=1,#p14=NULL
Note that the query now contains #p13 and #p14 where previously it had scalar values.
Related
I am trying to do a simple calculation for my data. When the Order value = 6, then subtract the values of order = 1 - 2 -3. It returns #error instead of the the answer. How can i make it work correctly?
= SWITCH(
Fields!Order.Value = 6,
Sum(IIF( Fields!Order.Value = 1 ,CDBL(Fields!Totals.Value),CDBL(0)))
- Sum(IIF( Fields!Ordering.Value = 2 ,CDBL(Fields!Totals.Value),CDBL(0)))
- Sum(IIF( Fields!Ordering.Value = 3 ,CDBL(Fields!Totals.Value),CDBL(0)))
,
1 = 1,Sum(Fields!Totals.Value)
)
I have made a function with mathematica and Im getting what I want from it however I am also getting 'Null' on the end and im not sure why.
Here is my code:
x = ""
ButterflyString[y_]:=For[i = 1, i < 8, i++, x = StringTake[y, {i}] <> x] x
My input:
ButterflyString["Wolfram"]
My output:
marfloW Null
As #Bill posted in the comments:
x = "";
ButterflyString[y_] :=
(For[i = 1, i < 8, i++, x = StringTake[y, {i}] <> x];
x)
This worked for me.
I have a table that has a column is_up_vote = true|false
I am trying to write a query using withCount() so it returns me the sum of true values and false values.
select COUNT(is_up_vote) from comment_votes WHERE is_up_vote = true returns 17
select COUNT(is_up_vote) from comment_votes WHERE is_up_vote = false returns 15
However I couldn't figure out how to get different of them, so the total returns 2.
What I tried is:
Model::withCount(['votes' => function($q) {
$q->selectRaw(
'(SUM (COUNT(is_up_vote) WHERE is_up_vote = true) - (COUNT(is_up_vote) WHERE is_up_vote = false) )'
);
}]);
But this returns 17+15 = 32
without SUM(), it's also returning 32.
$q->selectRaw(
'( (COUNT(is_up_vote) WHERE is_up_vote = true) - (COUNT(is_up_vote) WHERE is_up_vote = false) )'
);
What am I doing wrong?
Edit:
If I try one side, it ignores the where and still returns 32, so the where is not getting called (where it does in sql)
return $query->withCount(['votes' => function($q) {
$q->selectRaw('(COUNT(is_up_vote) WHERE is_up_vote = true)');
}]);
maunal sequel query returns 17:
select COUNT(is_up_vote) from comment_votes WHERE is_up_vote = true
Edit 2:
$query->withCount([
'votes as up_votes_count' => function($q) {
$q->where('is_up_vote', true);
},
'votes as down_votes_count' => function($q) {
$q->where('is_up_vote', false);
},
]);
The only thing that I could make work is this, but it'd need extra step for getting the total, so I didn't really like this approach. I'm sure someone more proficient with queries can come up with something with direct query.
withCount may not be able to handle this case. what about using addSelect to calculate the votes count.
return Model::addSelect(['votes_count' => Vote::selectRaw('( (COUNT(is_up_vote) WHERE is_up_vote = true) - (COUNT(is_up_vote) WHERE is_up_vote = false) )')
->whereColumn('parent_id', 'parents.id')
])->get();
I don't know whether the sub-query is gonna work. But you know the idea.
According to the instructions commented by #Jefferson Pessanha, just using Model::selectRaw('(abs(2 * sum(is_up_vote) - count(*)))')->get(); would be enough
create table comment_votes
(
is_up_vote tinyint(1) default 1 null
);
insert into comment_votes values (true),(true),(true),(true),(true),(true),(true),(true),(true),(true),(true),(true),(true),(true),(true),(true),(true);
insert into comment_votes values (false),(false),(false),(false),(false),(false),(false),(false),(false),(false),(false),(false),(false),(false),(false);
select COUNT(is_up_vote) from comment_votes WHERE is_up_vote = true;
returns 17
select COUNT(is_up_vote) from comment_votes WHERE is_up_vote = false;
returns 15
select (abs(2 * sum(is_up_vote) - count(*))) from comment_votes;
returns 2
Explain:
trueValues + falseValues = total
falseValues = total - trueValues
trueValues - falseValues = x
trueValues - (total - trueValues) = x
2 * trueValues - total = x
trueValues = sum(is_up_vote) [only trues stored as 1 are counted]
total = count(*)
Abs function is to convert the result to positive in case of negative
Isn't it correct?
Try this.
select
sum( if(is_up_vote= true, 1, 0) ) as uptrue,
sum( if(is_up_vote= false, 1, 0) ) as upfalse,
sum( if(is_up_vote= true, 1, -1) ) as updiff
from comment_votes
Edit: 1
Instead of checking if it is true or false, try this.
select
sum( if(is_up_vote, 1, 0) ) as uptrue,
sum( if(is_up_vote, 0, 1) ) as upfalse,
sum( if(is_up_vote, 1, -1) ) as updiff
from comment_votes
I am having a horrible time at grasping functions and tables. I've asked a question before that is similar to this but still am having problems getting this to work properly. So I will be more descriptive. But just when I think I understand it I completely confuse myself again. Here is what I am trying to accomplish:
I have a program that is receiving its input from an outside source. It needs to take that input, and basically "dissect" the strings to get the required information. Based on the information it receives, it moves onto the next phase or functions to do the appropriate actions. For example:
input is received as NY345,de,M,9900
I created a table that has all of the different ways the specific input can begin, such as:
local t = {["NY"] = 5, ["MS"] = 7, ["HG"] = 10, ["JX"] = 14, ["UY"] = 20}
Now I want to use a function to receive the input and look for k in t{} and use that to gather other variables...
function seek(input)
for k, v in pairs (seek) do
local info = string.match(input,k)
if info then
return {seekData = string.match(input,k..",(%d*),.*"), seekMult = seekData*v}
end
end
end
How far off am I?
If I had the table "t = {...}" above, and that contained other tables; how can I name each table inside of "t = {...}" and retrieve it for other equations? Such as if ["a"] = 8, the rest of that table was to be utilized? For example:
t={["a"] = 2, ["b"] = 3, ["c"] = "IOS"},{["a"] = 8, ["b"] = 9, ["c"] = "NVY"},{["a"] = 1, ["b"] = 5, ["c"] = "CWQ"}}
if a = 8, then b = 9 and c = "NVY"
I would like my function to search k (of each table) and compare it with the input. If that was found, then it would set the other two local variables to b and c?
Thanks for your help!
I will only answer question 1, as 2 and 3 should be separate questions. There are many ways to do this based on specifics you don't mention but assuming you have a table t like this:
t={
{["a"] = 2, ["b"] = 3, ["c"] = "IOS"},
{["a"] = 8, ["b"] = 9, ["c"] = "NVY"},
{["a"] = 1, ["b"] = 5, ["c"] = "CWQ"}
}
then a function that takes an a key value to look for and returns b and c:
function findItem(a, yourTable)
for i,tt in ipairs(yourTable) do
if tt.a == a then
return i, tt.b, tt.c
end
end
end
With this, if the input is k, then
i, b, c = findItem(k, t)
if i == nil then
print('could not find k')
else
print('found k at index ' .. i)
end
The findItem could of course just return the subtable found, and maybe you don't need index:
function findItem(a, yourTable)
for i,tt in ipairs(yourTable) do
if tt.a == a then
return tt
end
end
end
Basically I'm looking for something like
SELECT ordinal(my_number) FROM my_table
which would return
1st
11th
1071st
...
etc
but preferrably without the use of a stored procedure
I don't know of a built-in function but it's pretty easy to write:
SELECT
CONCAT(my_number, CASE
WHEN my_number%100 BETWEEN 11 AND 13 THEN "th"
WHEN my_number%10 = 1 THEN "st"
WHEN my_number%10 = 2 THEN "nd"
WHEN my_number%10 = 3 THEN "rd"
ELSE "th"
END)
FROM my_table;
mysql doesn't have support for this. You'll have to handle the strings in whichever language you are getting the mysql data from.
Based on Ken's code, a custom MySQL function would be as follows:
DELIMITER $$
CREATE FUNCTION ordinal(number BIGINT)
RETURNS VARCHAR(64)
DETERMINISTIC
BEGIN
DECLARE ord VARCHAR(64);
SET ord = (SELECT CONCAT(number, CASE
WHEN number%100 BETWEEN 11 AND 13 THEN "th"
WHEN number%10 = 1 THEN "st"
WHEN number%10 = 2 THEN "nd"
WHEN number%10 = 3 THEN "rd"
ELSE "th"
END));
RETURN ord;
END$$
DELIMITER ;
Then it can be used as:
SELECT ordinal(1) -- 1st
SELECT ordinal(11) -- 11th
SELECT ordinal(21) -- 21st
SELECT ordinal(my_number) FROM my_table
It is possible in MySQL using the string functions but it gets messy real fast. You'd better just do the suffix in the language you're using. For example, in PHP you could do something like this:
function ordSuffix($num) {
if(empty($num) || !is_numeric($num) || $num == 0) return $num;
$lastNum = substr($num, -1);
$suffix = 'th';
if($lastNum == 1 && $num != 11) { $suffix = 'st'; }
elseif($lastNum == 2 && $num != 12) { $suffix = 'nd'; }
elseif($lastNum == 3 && $num != 13) { $suffix = 'rd'; }
return $num.$suffix;
}
echo ordSuffix(4); // 4th
echo ordSuffix(1); // 1st
echo ordSuffix(12); // 12th
echo ordSuffix(1052); // 1052nd
I found a way that works for me but its a bit of a hack
DATE_FORMAT(CONCAT('2010-01-', my_number), '%D')
That works because currently the number I'm looking at never gets above 25. But it doesn't generalize well so someone might be entertained by this:
CONCAT(
IF(my_number % 100 BETWEEN 11 AND 13,
FLOOR(my_number / 100),
FLOOR(my_number / 10)),
DATE_FORMAT(
CONCAT('2010-01-',
IF(my_number % 100 BETWEEN 11 AND 13
my_number % 100,
my_number % 10)),
'%D'))
But that's a lot of work just to get at the DATE_FORMAT functionality when Ken's code is simpler.