我正在尝试使用子查询查找表中已完成的百分比。我可以使用以下命令成功获得所需的值,但是我担心当一个(或联接)执行操作时,我不必要地使用两个查询来到达那里:
SELECT (
CAST((SELECT COUNT(WO.[WORK_ORDER_ID])
FROM [NCH].[nch].[WORK_ORDER] WO JOIN [NCH].[nch].[TASK] T ON WO.[TASK_ID] = T.[TASK_ID]
WHERE WO.[LOT_ID] = 501 AND WO.[DRY_RUN_FLAG] != 1
AND WO.[COMPLETED_DATE] IS NOT NULL AND T.[TASK_TYPE_ID] = 2) AS float)
/
(CAST((SELECT COUNT(WO.[WORK_ORDER_ID])
FROM [NCH].[nch].[WORK_ORDER] WO JOIN [NCH].[nch].[TASK] T ON WO.[TASK_ID] = T.[TASK_ID]
WHERE WO.[LOT_ID] = 501 AND T.[TASK_TYPE_ID] = 2) as Float))
) * 100 AS PERCENT_ROUGH_COMPLETED
具体来说,我所关注的是where子句。我在重复完全相同的查询,除了where条件。可以在同一张桌子上用JOIN完成吗?多次联接使我感到困惑,SQL是我最薄弱的技能之一。我觉得此查询可能会收紧,因为我将不得不在更大的查询中重复此查询。
编辑
通过使用CASE,我能够正确配置较大的SQL查询。我以前从未写过如此复杂的查询,因此,如果看起来过于复杂,请原谅:
SELECT L.[LOT_ID]
,L.[LOT_NUMBER]
,L.[JOBSITE_ID]
,L.[PHASE_ID]
,L.[MODEL_ID]
,M.[SQUARE_FOOTAGE]
,M.[MODEL_NAME]
,P.[PHASE_NAME]
-- Case 1
,CASE
WHEN P.[ROUGH_SCHEDULE_FLAG] != 0
THEN
(SELECT (SELECT AVG(CASE WHEN WO.[DRY_RUN_FLAG] <> 1 AND WO.[COMPLETED_DATE] IS NOT NULL THEN 1.0 ELSE 0 END)
FROM [NCH].[nch].[WORK_ORDER] WO
JOIN [NCH].[nch].[TASK] T ON WO.[TASK_ID] = T.[TASK_ID]
WHERE WO.[LOT_ID] = L.[LOT_ID] AND T.[TASK_TYPE_ID] = 1) * 100)
ELSE 0
END AS ROUGH_PERCENT_COMPLETED,
-- Case 2
CASE
WHEN P.[INTERIOR_SCHEDULE_FLAG] != 0
THEN
(SELECT (SELECT AVG(CASE WHEN WO.[DRY_RUN_FLAG] <> 1 AND WO.[COMPLETED_DATE] IS NOT NULL THEN 1.0 ELSE 0 END)
FROM [NCH].[nch].[WORK_ORDER] WO
JOIN [NCH].[nch].[TASK] T ON WO.[TASK_ID] = T.[TASK_ID]
WHERE WO.[LOT_ID] = L.[LOT_ID] AND T.[TASK_TYPE_ID] = 2) * 100)
ELSE 0
END AS INTERIOR_PERCENT_COMPLETED,
-- Case 3
CASE
WHEN P.[WASH_SCHEDULE_FLAG] != 0
THEN
(SELECT (SELECT AVG(CASE WHEN WO.[DRY_RUN_FLAG] <> 1 AND WO.[COMPLETED_DATE] IS NOT NULL THEN 1.0 ELSE 0 END)
FROM [NCH].[nch].[WORK_ORDER] WO
JOIN [NCH].[nch].[TASK] T ON WO.[TASK_ID] = T.[TASK_ID]
WHERE WO.[LOT_ID] = L.[LOT_ID] AND T.[TASK_TYPE_ID] = 3) * 100)
ELSE 0
END AS WASH_PERCENT_COMPLETED
FROM [NCH].[nch].[LOT] L
JOIN [NCH].[nch].[MODEL] M ON L.[MODEL_ID] = M.[MODEL_ID]
JOIN [NCH].[nch].[PHASE] P ON L.[PHASE_ID] = P.[PHASE_ID]
L. [JOBSITE_ID] = 1502
答案 0 :(得分:2)
我可以简化为:
select avg(case when wo.dry_run_flalg <> 1 and
wo.completed_date is not null
then 1.0 else 0
end) as ratio
from [NCH].[nch].[WORK_ORDER] wo join
[NCH].[nch].[TASK] t
on wo.[TASK_ID] = t.[TASK_ID]
where wo.lot_id = 501 and
wo.work_order_id is not null and
t.task_type_id = 2
答案 1 :(得分:1)
您可以使用#include <cmath>
#include <vector>
#include <string>
#include <limits>
#include <iomanip>
#include <iostream>
// glad.h is generated by the following command:
// glad --out-path=. --generator=c --omit-khrplatform --api="gl=3.3" --profile=core --extensions=
#include "glad/glad.h"
#include <GL/freeglut.h>
#include <glm/glm.hpp>
using glm::vec4;
GLuint vao, vbo;
GLuint texFBO;
GLuint program;
GLuint fbo;
int width=1, height=2;
void printShaderOutput(int texW, int texH)
{
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texFBO);
std::vector<vec4> data(texW*texH);
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_FLOAT, data.data());
std::cout << "a,b,sum,relError(sum),note\n";
for(int i=0;i<width;++i)
{
const auto a=double(data[i+width*0].x)+double(data[i+width*0].y);
const auto b=double(data[i+width*0].z)+double(data[i+width*0].w);
const auto sum=double(data[i+width*1].x)+double(data[i+width*1].y);
const auto trueSum=a+b;
const auto sumErr=(sum-trueSum)/trueSum;
std::cout << std::setprecision(std::numeric_limits<double>::max_digits10)
<< a << ',' << b << ','
<< sum << ','
<< std::setprecision(3)
<< sumErr << ','
<< (std::abs(sumErr)>1e-14 ? "WARN" : "OK")
<< '\n';
}
std::cout.flush();
}
GLuint makeShader(GLenum type, std::string const& srcStr)
{
const auto shader=glCreateShader(type);
const GLint srcLen=srcStr.size();
const GLchar*const src=srcStr.c_str();
glShaderSource(shader, 1, &src, &srcLen);
glCompileShader(shader);
GLint status=-1;
glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
assert(glGetError()==GL_NO_ERROR);
assert(status);
return shader;
}
void loadShaders()
{
program=glCreateProgram();
const auto vertexShader=makeShader(GL_VERTEX_SHADER, 1+R"(
#version 330
in vec4 vertex;
void main() { gl_Position=vertex; }
)");
glAttachShader(program, vertexShader);
const auto fragmentShader=makeShader(GL_FRAGMENT_SHADER, 1+R"(
#version 330
#extension GL_ARB_gpu_shader5 : require
vec2 ds_add(vec2 dsa, vec2 dsb)
{
precise float t1 = dsa.x + dsb.x;
precise float e = t1 - dsa.x;
precise float t2 = ((dsb.x - e) + (dsa.x - (t1 - e))) + dsa.y + dsb.y;
precise vec2 dsc;
dsc.x = t1 + t2;
dsc.y = t2 - (dsc.x - t1);
return dsc;
}
uniform vec2 a, b;
out vec4 color;
void main()
{
if(gl_FragCoord.y<1) // first row
color=vec4(a,b);
else if(gl_FragCoord.y<2) // second row
color=vec4(ds_add(a,b),0,0);
}
)");
glAttachShader(program, fragmentShader);
glLinkProgram(program);
GLint status=0;
glGetProgramiv(program, GL_LINK_STATUS, &status);
assert(glGetError()==GL_NO_ERROR);
assert(status);
glDetachShader(program, fragmentShader);
glDeleteShader(fragmentShader);
glDetachShader(program, vertexShader);
glDeleteShader(vertexShader);
}
void setupBuffers()
{
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
const GLfloat vertices[]=
{
-1, -1,
1, -1,
-1, 1,
1, 1,
};
glBufferData(GL_ARRAY_BUFFER, sizeof vertices, vertices, GL_STATIC_DRAW);
constexpr GLuint attribIndex=0;
constexpr int coordsPerVertex=2;
glVertexAttribPointer(attribIndex, coordsPerVertex, GL_FLOAT, false, 0, 0);
glEnableVertexAttribArray(attribIndex);
glBindVertexArray(0);
}
bool init()
{
if(!gladLoadGL())
{
std::cerr << "Failed to initialize GLAD\n";
return false;
}
if(!GLAD_GL_VERSION_3_3)
{
std::cerr << "OpenGL 3.3 not supported\n";
return false;
}
glGenTextures(1, &texFBO);
glGenFramebuffers(1,&fbo);
loadShaders();
setupBuffers();
glViewport(0,0,width,height);
glBindTexture(GL_TEXTURE_2D,texFBO);
glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA32F,width,height,0,GL_RGBA,GL_UNSIGNED_BYTE,nullptr);
glBindTexture(GL_TEXTURE_2D,0);
glBindFramebuffer(GL_FRAMEBUFFER,fbo);
glFramebufferTexture2D(GL_FRAMEBUFFER,GL_COLOR_ATTACHMENT0,GL_TEXTURE_2D,texFBO,0);
const auto status=glCheckFramebufferStatus(GL_FRAMEBUFFER);
assert(status==GL_FRAMEBUFFER_COMPLETE);
glBindFramebuffer(GL_FRAMEBUFFER,0);
return true;
}
void display()
{
const static bool inited=init();
if(!inited) std::exit(1);
glBindFramebuffer(GL_FRAMEBUFFER,fbo);
glUseProgram(program);
#define SPLIT_DOUBLE_TO_FLOATS(x) GLfloat(x),GLfloat(x-GLfloat(x))
glUniform2f(glGetUniformLocation(program,"a"),SPLIT_DOUBLE_TO_FLOATS(3.1415926535897932));
glUniform2f(glGetUniformLocation(program,"b"),SPLIT_DOUBLE_TO_FLOATS(2.7182818284590452));
glUniform1f(glGetUniformLocation(program,"rtWidth"),width);
glBindVertexArray(vao);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glBindVertexArray(0);
printShaderOutput(width, height);
std::exit(0);
glFinish();
}
int main(int argc, char** argv)
{
glutInitContextVersion(3,3);
glutInitContextProfile(GLUT_CORE_PROFILE);
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB);
glutInitWindowSize(width, height);
glutCreateWindow("Test");
glutDisplayFunc(display);
glutMainLoop();
}
来完成。我认为最好使用数字(十进制)而不是CASE
。 float
是一种可能导致错误结果的近似数据类型。您可以了解有关此here的更多信息。
float