在具有不同where子句的子查询中查找百分比

时间:2019-05-25 20:19:06

标签: sql sql-server

我正在尝试使用子查询查找表中已完成的百分比。我可以使用以下命令成功获得所需的值,但是我担心当一个(或联接)执行操作时,我不必要地使用两个查询来到达那里:

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

result set

2 个答案:

答案 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(); } 来完成。我认为最好使用数字(十进制)而不是CASEfloat是一种可能导致错误结果的近似数据类型。您可以了解有关此here的更多信息。

float